[fuchsia] Cleanup WebEngineBrowserTestBase.

Replace calls to WebEngineBrowserTestBase::CreateFrame(), and associated
NavigationController and NavigationListener intiialization, with the
cr_fuchsia::FrameForTest helper.

Bug: 1200314
Change-Id: I03796166d0da3fe1c8f83aa0bc1e8def44d355a6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2892669
Commit-Queue: Wez <wez@chromium.org>
Auto-Submit: Wez <wez@chromium.org>
Reviewed-by: David Dorwin <ddorwin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#913355}
diff --git a/fuchsia/engine/browser/autoplay_browsertest.cc b/fuchsia/engine/browser/autoplay_browsertest.cc
index d57bec5..1dc3274 100644
--- a/fuchsia/engine/browser/autoplay_browsertest.cc
+++ b/fuchsia/engine/browser/autoplay_browsertest.cc
@@ -10,6 +10,7 @@
 #include "fuchsia/base/test/test_navigation_listener.h"
 #include "fuchsia/engine/browser/context_impl.h"
 #include "fuchsia/engine/browser/frame_impl.h"
+#include "fuchsia/engine/test/frame_for_test.h"
 #include "fuchsia/engine/test/test_data.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom.h"
@@ -43,17 +44,12 @@
  protected:
   // Creates a Frame with |navigation_listener_| attached and |policy|
   // applied.
-  fuchsia::web::FramePtr CreateFrame(fuchsia::web::AutoplayPolicy policy) {
+  cr_fuchsia::FrameForTest CreateFrame(fuchsia::web::AutoplayPolicy policy) {
     fuchsia::web::CreateFrameParams params;
     params.set_autoplay_policy(policy);
-    fuchsia::web::FramePtr frame = WebEngineBrowserTest::CreateFrameWithParams(
-        &navigation_listener_, std::move(params));
-    frame->GetNavigationController(controller_.NewRequest());
+    auto frame = cr_fuchsia::FrameForTest::Create(context(), std::move(params));
     return frame;
   }
-
-  cr_fuchsia::TestNavigationListener navigation_listener_;
-  fuchsia::web::NavigationControllerPtr controller_;
 };
 
 IN_PROC_BROWSER_TEST_F(
@@ -62,62 +58,63 @@
   const GURL kUrl(embedded_test_server()->GetURL(kAutoplayVp8Url));
   constexpr const char kPageLoadedTitle[] = "initial title";
 
-  fuchsia::web::FramePtr frame =
+  cr_fuchsia::FrameForTest frame =
       CreateFrame(fuchsia::web::AutoplayPolicy::REQUIRE_USER_ACTIVATION);
 
   fuchsia::web::LoadUrlParams params;
-  EXPECT_TRUE(
-      cr_fuchsia::LoadUrlAndExpectResponse(controller_.get(), {}, kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, kPageLoadedTitle);
+  EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+      frame.GetNavigationController(), {}, kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl, kPageLoadedTitle);
 
   context_impl()
-      ->GetFrameImplForTest(&frame)
+      ->GetFrameImplForTest(&frame.ptr())
       ->web_contents_for_test()
       ->GetMainFrame()
       ->NotifyUserActivation(
           blink::mojom::UserActivationNotificationType::kTest);
 
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "playing");
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl, "playing");
 }
 
 IN_PROC_BROWSER_TEST_F(AutoplayTest,
                        UserActivationPolicy_UserActivatedNavigation) {
   const GURL kUrl(embedded_test_server()->GetURL(kAutoplayVp8Url));
 
-  fuchsia::web::FramePtr frame =
+  cr_fuchsia::FrameForTest frame =
       CreateFrame(fuchsia::web::AutoplayPolicy::REQUIRE_USER_ACTIVATION);
 
   fuchsia::web::LoadUrlParams params;
   params.set_was_user_activated(true);
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller_.get(), std::move(params), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "playing");
+      frame.GetNavigationController(), std::move(params), kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl, "playing");
 }
 
 IN_PROC_BROWSER_TEST_F(AutoplayTest, UserActivationPolicy_NoUserActivation) {
   const GURL kUrl(embedded_test_server()->GetURL(kAutoplayVp8Url));
 
-  fuchsia::web::FramePtr frame =
+  cr_fuchsia::FrameForTest frame =
       CreateFrame(fuchsia::web::AutoplayPolicy::REQUIRE_USER_ACTIVATION);
 
   fuchsia::web::LoadUrlParams params;
   params.set_was_user_activated(false);
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller_.get(), std::move(params), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "blocked");
+      frame.GetNavigationController(), std::move(params), kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl, "blocked");
 }
 
 IN_PROC_BROWSER_TEST_F(AutoplayTest,
                        AllowAllPolicy_DefaultNotUserActivatedNavigation) {
   const GURL kUrl(embedded_test_server()->GetURL(kAutoplayVp8Url));
 
-  fuchsia::web::FramePtr frame =
+  cr_fuchsia::FrameForTest frame =
       CreateFrame(fuchsia::web::AutoplayPolicy::ALLOW);
 
   // The page is deliberately not user activated.
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller_.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "playing");
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl, "playing");
 }
diff --git a/fuchsia/engine/browser/cast_streaming_browsertest.cc b/fuchsia/engine/browser/cast_streaming_browsertest.cc
index 5f6115a..6dcfc98 100644
--- a/fuchsia/engine/browser/cast_streaming_browsertest.cc
+++ b/fuchsia/engine/browser/cast_streaming_browsertest.cc
@@ -15,6 +15,7 @@
 #include "fuchsia/base/test/test_navigation_listener.h"
 #include "fuchsia/engine/browser/context_impl.h"
 #include "fuchsia/engine/browser/frame_impl.h"
+#include "fuchsia/engine/test/frame_for_test.h"
 #include "fuchsia/engine/test/test_data.h"
 #include "fuchsia/engine/test/web_engine_browser_test.h"
 #include "media/base/media_util.h"
@@ -55,14 +56,6 @@
 
   CastStreamingBaseTest(const CastStreamingBaseTest&) = delete;
   CastStreamingBaseTest& operator=(const CastStreamingBaseTest&) = delete;
-
- protected:
-  // Creates a Frame with |navigation_listener_| attached.
-  fuchsia::web::FramePtr CreateFrame() {
-    return WebEngineBrowserTest::CreateFrame(&navigation_listener_);
-  }
-
-  cr_fuchsia::TestNavigationListener navigation_listener_;
 };
 
 // Test fixture for Cast Streaming tests with the Cast Streaming Receiver flag
@@ -102,21 +95,22 @@
 // command line switch is not set fails as expected.
 IN_PROC_BROWSER_TEST_F(CastStreamingDisabledTest, LoadFailure) {
   ASSERT_TRUE(embedded_test_server()->Start());
-  GURL page_url(embedded_test_server()->GetURL(kCastStreamingReceiverPath));
+  const GURL page_url(
+      embedded_test_server()->GetURL(kCastStreamingReceiverPath));
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), page_url.spec()));
-  navigation_listener_.RunUntilTitleEquals("error");
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      page_url.spec()));
+  frame.navigation_listener().RunUntilTitleEquals("error");
 }
 
 // Check that attempting to load the cast streaming media source URL when the
 // command line switch is set properly succeeds.
 IN_PROC_BROWSER_TEST_F(CastStreamingTest, LoadSuccess) {
   ASSERT_TRUE(embedded_test_server()->Start());
-  const GURL kPageUrl(
+  const GURL page_url(
       embedded_test_server()->GetURL(kCastStreamingReceiverPath));
   fuchsia::mem::Buffer ignored_message_string =
       cr_fuchsia::MemBufferFromString("hi", "test");
@@ -138,7 +132,8 @@
                            GetDefaultAudioConfig(), GetDefaultVideoConfig()));
 
   // Create a Frame and set the Receiver MessagePort on it.
-  fuchsia::web::FramePtr frame = CreateFrame();
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
   cr_fuchsia::ResultReceiver<fuchsia::web::Frame_PostMessage_Result>
       post_result(base::DoNothing::Repeatedly());
   frame->PostMessage(
@@ -147,13 +142,12 @@
           std::move(message_port_request), std::move(ignored_message_string)),
       cr_fuchsia::CallbackToFitFunction(post_result.GetReceiveCallback()));
 
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kPageUrl.spec()));
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      page_url.spec()));
 
   sender.RunUntilStarted();
-  navigation_listener_.RunUntilTitleEquals("canplay");
+  frame.navigation_listener().RunUntilTitleEquals("canplay");
 
   EXPECT_NE(sender.audio_decoder_config(), absl::nullopt);
   EXPECT_NE(sender.video_decoder_config(), absl::nullopt);
@@ -186,7 +180,8 @@
                            GetDefaultAudioConfig(), GetDefaultVideoConfig()));
 
   // Create a Frame and set the Receiver MessagePort on it.
-  fuchsia::web::FramePtr frame = CreateFrame();
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
   cr_fuchsia::ResultReceiver<fuchsia::web::Frame_PostMessage_Result>
       post_result(base::DoNothing::Repeatedly());
   frame->PostMessage(
@@ -195,13 +190,12 @@
           std::move(message_port_request), std::move(ignored_message_string)),
       cr_fuchsia::CallbackToFitFunction(post_result.GetReceiveCallback()));
 
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kPageUrl.spec()));
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kPageUrl.spec()));
 
   sender.RunUntilStarted();
-  navigation_listener_.RunUntilTitleEquals("canplay");
+  frame.navigation_listener().RunUntilTitleEquals("canplay");
 
   EXPECT_EQ(sender.audio_decoder_config(), absl::nullopt);
   EXPECT_NE(sender.video_decoder_config(), absl::nullopt);
diff --git a/fuchsia/engine/browser/content_directory_browsertest.cc b/fuchsia/engine/browser/content_directory_browsertest.cc
index b6c7167f..e99ea09 100644
--- a/fuchsia/engine/browser/content_directory_browsertest.cc
+++ b/fuchsia/engine/browser/content_directory_browsertest.cc
@@ -22,6 +22,7 @@
 #include "fuchsia/base/test/test_navigation_listener.h"
 #include "fuchsia/engine/browser/content_directory_loader_factory.h"
 #include "fuchsia/engine/switches.h"
+#include "fuchsia/engine/test/frame_for_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/url_util.h"
 
@@ -85,6 +86,9 @@
   ContentDirectoryTest() = default;
   ~ContentDirectoryTest() override = default;
 
+  ContentDirectoryTest(const ContentDirectoryTest&) = delete;
+  ContentDirectoryTest& operator=(const ContentDirectoryTest&) = delete;
+
   void SetUp() override {
     // Set this flag early so that the fuchsia-dir:// scheme will be
     // registered at browser startup.
@@ -115,74 +119,61 @@
     cr_fuchsia::WebEngineBrowserTest::SetUpOnMainThread();
   }
 
- protected:
-  // Creates a Frame with |navigation_listener_| attached.
-  fuchsia::web::FramePtr CreateFrame() {
-    return WebEngineBrowserTest::CreateFrame(&navigation_listener_);
-  }
-
-  cr_fuchsia::TestNavigationListener navigation_listener_;
-
  private:
   url::ScopedSchemeRegistryForTests scoped_registry_;
 
   std::unique_ptr<ScopedBindContentDirectory> testdata_content_directory_;
   std::unique_ptr<ScopedBindContentDirectory> alternate_content_directory_;
-
-  DISALLOW_COPY_AND_ASSIGN(ContentDirectoryTest);
 };
 
 IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, Navigate) {
   const GURL kUrl("fuchsia-dir://testdata/title1.html");
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlEquals(kUrl);
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlEquals(kUrl);
 }
 
 // Navigate to a resource stored under a secondary provider.
 IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, NavigateAlternate) {
   const GURL kUrl("fuchsia-dir://alternate/title1.html");
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlEquals(kUrl);
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlEquals(kUrl);
 }
 
 IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, ScriptSubresource) {
   const GURL kUrl("fuchsia-dir://testdata/include_script.html");
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "title set by script");
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl,
+                                                        "title set by script");
 }
 
 IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, ImgSubresource) {
   const GURL kUrl("fuchsia-dir://testdata/include_image.html");
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "image fetched");
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl, "image fetched");
 }
 
 // Reads content sourced from VFS PseudoDirs and VmoFiles.
@@ -201,71 +192,68 @@
 
   // Access the VmoFile under the PseudoDir.
   const GURL kUrl("fuchsia-dir://pseudo-dir/title1.html");
-  fuchsia::web::FramePtr frame = CreateFrame();
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "title 1");
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl, "title 1");
 }
 
 // Verify that resource providers are origin-isolated.
 IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, ScriptSrcCrossOriginBlocked) {
   const GURL kUrl("fuchsia-dir://testdata/cross_origin_include_script.html");
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   // If the cross-origin script succeeded, then we should see "title set by
   // script". If "not clobbered" remains set, then we know that CROS enforcement
   // is working.
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "same origin ftw");
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl,
+                                                        "same origin ftw");
 }
 
 IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, CrossOriginImgBlocked) {
   const GURL kUrl("fuchsia-dir://testdata/cross_origin_include_image.html");
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
 
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "image rejected");
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl, "image rejected");
 }
 
 IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, MetadataFileParsed) {
   const GURL kUrl("fuchsia-dir://testdata/mime_override.html");
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(
       kUrl, "content-type: text/bleep; charset=US-ASCII");
 }
 
 IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, BadMetadataFile) {
   const GURL kUrl("fuchsia-dir://testdata/mime_override_invalid.html");
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl,
-                                                 "content-type: text/html");
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(
+      kUrl, "content-type: text/html");
 }
 
 IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, BigFilesAreSniffable) {
@@ -289,13 +277,13 @@
 
   // Access the VmoFile under the PseudoDir.
   const GURL kUrl("fuchsia-dir://pseudo-dir/test.html");
-  fuchsia::web::FramePtr frame = CreateFrame();
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl,
-                                                 "content-type: text/html");
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(
+      kUrl, "content-type: text/html");
 }
 
 }  // namespace
diff --git a/fuchsia/engine/browser/context_impl_browsertest.cc b/fuchsia/engine/browser/context_impl_browsertest.cc
index f44995e..90601d2 100644
--- a/fuchsia/engine/browser/context_impl_browsertest.cc
+++ b/fuchsia/engine/browser/context_impl_browsertest.cc
@@ -8,6 +8,7 @@
 #include "fuchsia/base/test/result_receiver.h"
 #include "fuchsia/base/test/test_navigation_listener.h"
 #include "fuchsia/engine/switches.h"
+#include "fuchsia/engine/test/frame_for_test.h"
 #include "fuchsia/engine/test/web_engine_browser_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/url_constants.h"
@@ -25,11 +26,6 @@
   ContextImplTest& operator=(const ContextImplTest&) = delete;
 
  protected:
-  // Creates a Frame with |navigation_listener_| attached.
-  fuchsia::web::FramePtr CreateFrame() {
-    return WebEngineBrowserTest::CreateFrame(&navigation_listener_);
-  }
-
   // Synchronously gets the list of all cookies from the fuchsia.web.Context.
   std::vector<fuchsia::web::Cookie> GetCookies() {
     base::RunLoop get_cookies_loop;
@@ -65,8 +61,6 @@
 
     return cookies;
   }
-
-  cr_fuchsia::TestNavigationListener navigation_listener_;
 };
 
 fuchsia::web::Cookie CreateExpectedCookie() {
@@ -92,16 +86,15 @@
 // be retrieved via the CookieManager API.
 IN_PROC_BROWSER_TEST_F(ContextImplTest, PersistentCookieStore) {
   ASSERT_TRUE(embedded_test_server()->Start());
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   const GURL kSetCookieUrl(
       embedded_test_server()->GetURL("/set-cookie?foo=bar"));
-  cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kSetCookieUrl.spec());
-  navigation_listener_.RunUntilUrlEquals(kSetCookieUrl);
+  cr_fuchsia::LoadUrlAndExpectResponse(frame.GetNavigationController(),
+                                       fuchsia::web::LoadUrlParams(),
+                                       kSetCookieUrl.spec());
+  frame.navigation_listener().RunUntilUrlEquals(kSetCookieUrl);
 
   std::vector<fuchsia::web::Cookie> cookies = GetCookies();
   ASSERT_EQ(cookies.size(), 1u);
@@ -110,7 +103,7 @@
 
   // Check that the cookie persists beyond the lifetime of the Frame by
   // releasing the Frame and re-querying the CookieStore.
-  frame.Unbind();
+  frame = cr_fuchsia::FrameForTest();
   base::RunLoop().RunUntilIdle();
 
   cookies = GetCookies();
@@ -126,43 +119,39 @@
   IncognitoContextImplTest() = default;
   ~IncognitoContextImplTest() override = default;
 
+  IncognitoContextImplTest(const IncognitoContextImplTest&) = delete;
+  IncognitoContextImplTest& operator=(const IncognitoContextImplTest&) = delete;
+
   void SetUp() override {
     base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kIncognito);
     ContextImplTest::SetUp();
   }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(IncognitoContextImplTest);
 };
 
 // Verify that the browser can be initialized without a persistent data
 // directory.
 IN_PROC_BROWSER_TEST_F(IncognitoContextImplTest, NavigateFrame) {
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), url::kAboutBlankURL));
-  navigation_listener_.RunUntilUrlEquals(GURL(url::kAboutBlankURL));
-
-  frame.Unbind();
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      url::kAboutBlankURL));
+  frame.navigation_listener().RunUntilUrlEquals(GURL(url::kAboutBlankURL));
 }
 
 // In-memory cookie store stores cookies, and is accessible via CookieManager.
 IN_PROC_BROWSER_TEST_F(IncognitoContextImplTest, InMemoryCookieStore) {
   ASSERT_TRUE(embedded_test_server()->Start());
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   const GURL kSetCookieUrl(
       embedded_test_server()->GetURL("/set-cookie?foo=bar"));
-  cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kSetCookieUrl.spec());
-  navigation_listener_.RunUntilUrlEquals(kSetCookieUrl);
+  cr_fuchsia::LoadUrlAndExpectResponse(frame.GetNavigationController(),
+                                       fuchsia::web::LoadUrlParams(),
+                                       kSetCookieUrl.spec());
+  frame.navigation_listener().RunUntilUrlEquals(kSetCookieUrl);
 
   std::vector<fuchsia::web::Cookie> cookies = GetCookies();
   ASSERT_EQ(cookies.size(), 1u);
diff --git a/fuchsia/engine/browser/explicit_sites_filter_browsertest.cc b/fuchsia/engine/browser/explicit_sites_filter_browsertest.cc
index 8daa3d4..48b24202 100644
--- a/fuchsia/engine/browser/explicit_sites_filter_browsertest.cc
+++ b/fuchsia/engine/browser/explicit_sites_filter_browsertest.cc
@@ -12,9 +12,11 @@
 #include "content/public/test/browser_test.h"
 #include "fuchsia/base/mem_buffer_util.h"
 #include "fuchsia/base/test/frame_test_util.h"
+#include "fuchsia/base/test/test_navigation_listener.h"
 #include "fuchsia/engine/browser/context_impl.h"
 #include "fuchsia/engine/browser/frame_impl.h"
 #include "fuchsia/engine/browser/frame_impl_browser_test_base.h"
+#include "fuchsia/engine/test/frame_for_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -79,109 +81,88 @@
 };
 
 IN_PROC_BROWSER_TEST_F(ExplicitSitesFilterTest, FilterDisabled_SiteAllowed) {
-  fuchsia::web::CreateFrameParams params;
-
-  fuchsia::web::FramePtr frame = WebEngineBrowserTest::CreateFrameWithParams(
-      &navigation_listener_, std::move(params));
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   SetPageIsNotExplicit();
 
   fuchsia::web::NavigationControllerPtr controller;
   frame->GetNavigationController(controller.NewRequest());
-  EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(controller.get(), {},
-                                                   GetPage1UrlSpec()));
+  EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+      frame.GetNavigationController(), {}, GetPage1UrlSpec()));
 
-  navigation_listener_.RunUntilTitleEquals(kPage1Title);
+  frame.navigation_listener().RunUntilTitleEquals(kPage1Title);
 }
 
 IN_PROC_BROWSER_TEST_F(ExplicitSitesFilterTest, FilterDisabled_SiteBlocked) {
-  fuchsia::web::CreateFrameParams params;
-
-  fuchsia::web::FramePtr frame = WebEngineBrowserTest::CreateFrameWithParams(
-      &navigation_listener_, std::move(params));
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   SetPageIsExplicit();
 
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
-  EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(controller.get(), {},
-                                                   GetPage1UrlSpec()));
+  EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+      frame.GetNavigationController(), {}, GetPage1UrlSpec()));
 
-  navigation_listener_.RunUntilTitleEquals(kPage1Title);
+  frame.navigation_listener().RunUntilTitleEquals(kPage1Title);
 }
 
 IN_PROC_BROWSER_TEST_F(ExplicitSitesFilterTest, DefaultErrorPage_SiteAllowed) {
   fuchsia::web::CreateFrameParams params;
   params.set_explicit_sites_filter_error_page(
       fuchsia::mem::Data::WithBytes({}));
-
-  fuchsia::web::FramePtr frame = WebEngineBrowserTest::CreateFrameWithParams(
-      &navigation_listener_, std::move(params));
+  auto frame = cr_fuchsia::FrameForTest::Create(context(), std::move(params));
 
   SetPageIsNotExplicit();
 
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
-  EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(controller.get(), {},
-                                                   GetPage1UrlSpec()));
+  EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+      frame.GetNavigationController(), {}, GetPage1UrlSpec()));
 
-  navigation_listener_.RunUntilTitleEquals(kPage1Title);
+  frame.navigation_listener().RunUntilTitleEquals(kPage1Title);
 }
 
 IN_PROC_BROWSER_TEST_F(ExplicitSitesFilterTest, DefaultErrorPage_SiteBlocked) {
   fuchsia::web::CreateFrameParams params;
   params.set_explicit_sites_filter_error_page(
       fuchsia::mem::Data::WithBytes({}));
-
-  fuchsia::web::FramePtr frame = WebEngineBrowserTest::CreateFrameWithParams(
-      &navigation_listener_, std::move(params));
+  auto frame = cr_fuchsia::FrameForTest::Create(context(), std::move(params));
 
   SetPageIsExplicit();
 
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
-  EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(controller.get(), {},
-                                                   GetPage1UrlSpec()));
+  EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+      frame.GetNavigationController(), {}, GetPage1UrlSpec()));
 
   // The page title is the URL for which navigation failed without the scheme
   // part ("http://");
   std::string expected_title = GetPage1UrlSpec().erase(0, 7);
-  navigation_listener_.RunUntilErrorPageIsLoadedAndTitleEquals(expected_title);
+  frame.navigation_listener().RunUntilErrorPageIsLoadedAndTitleEquals(
+      expected_title);
 }
 
 IN_PROC_BROWSER_TEST_F(ExplicitSitesFilterTest, CustomErrorPage_SiteAllowed) {
   fuchsia::web::CreateFrameParams params;
   params.set_explicit_sites_filter_error_page(
       MemDataBytesFromShortString(kCustomExplicitSitesErrorPage));
-
-  fuchsia::web::FramePtr frame = WebEngineBrowserTest::CreateFrameWithParams(
-      &navigation_listener_, std::move(params));
+  auto frame = cr_fuchsia::FrameForTest::Create(context(), std::move(params));
 
   SetPageIsNotExplicit();
 
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
-  EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(controller.get(), {},
-                                                   GetPage1UrlSpec()));
+  EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+      frame.GetNavigationController(), {}, GetPage1UrlSpec()));
 
-  navigation_listener_.RunUntilTitleEquals(kPage1Title);
+  frame.navigation_listener().RunUntilTitleEquals(kPage1Title);
 }
 
 IN_PROC_BROWSER_TEST_F(ExplicitSitesFilterTest, CustomErrorPage_SiteBlocked) {
   fuchsia::web::CreateFrameParams params;
   params.set_explicit_sites_filter_error_page(
       MemDataBytesFromShortString(kCustomExplicitSitesErrorPage));
-
-  fuchsia::web::FramePtr frame = WebEngineBrowserTest::CreateFrameWithParams(
-      &navigation_listener_, std::move(params));
+  auto frame = cr_fuchsia::FrameForTest::Create(context(), std::move(params));
 
   SetPageIsExplicit();
 
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
-  EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(controller.get(), {},
-                                                   GetPage1UrlSpec()));
+  EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+      frame.GetNavigationController(), {}, GetPage1UrlSpec()));
 
-  navigation_listener_.RunUntilErrorPageIsLoadedAndTitleEquals(
+  frame.navigation_listener().RunUntilErrorPageIsLoadedAndTitleEquals(
       kCustomErrorPageTitle);
 }
diff --git a/fuchsia/engine/browser/frame_impl_browser_test_base.cc b/fuchsia/engine/browser/frame_impl_browser_test_base.cc
index beaf240..fb9404ac 100644
--- a/fuchsia/engine/browser/frame_impl_browser_test_base.cc
+++ b/fuchsia/engine/browser/frame_impl_browser_test_base.cc
@@ -13,10 +13,6 @@
   set_test_server_root(base::FilePath(cr_fuchsia::kTestServerRoot));
 }
 
-fuchsia::web::FramePtr FrameImplTestBase::CreateFrame() {
-  return WebEngineBrowserTest::CreateFrame(nullptr);
-}
-
 void FrameImplTestBaseWithServer::SetUpOnMainThread() {
   FrameImplTestBase::SetUpOnMainThread();
 
@@ -27,7 +23,3 @@
 FrameImplTestBaseWithServer::FrameImplTestBaseWithServer() {
   set_test_server_root(base::FilePath(cr_fuchsia::kTestServerRoot));
 }
-
-fuchsia::web::FramePtr FrameImplTestBaseWithServer::CreateFrame() {
-  return WebEngineBrowserTest::CreateFrame(&navigation_listener_);
-}
\ No newline at end of file
diff --git a/fuchsia/engine/browser/frame_impl_browser_test_base.h b/fuchsia/engine/browser/frame_impl_browser_test_base.h
index e310163..33df17e9 100644
--- a/fuchsia/engine/browser/frame_impl_browser_test_base.h
+++ b/fuchsia/engine/browser/frame_impl_browser_test_base.h
@@ -5,7 +5,6 @@
 #ifndef FUCHSIA_ENGINE_BROWSER_FRAME_IMPL_BROWSER_TEST_BASE_H_
 #define FUCHSIA_ENGINE_BROWSER_FRAME_IMPL_BROWSER_TEST_BASE_H_
 
-#include "fuchsia/base/test/test_navigation_listener.h"
 #include "fuchsia/engine/test/web_engine_browser_test.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 
@@ -19,9 +18,6 @@
  protected:
   FrameImplTestBase();
   ~FrameImplTestBase() override = default;
-
-  // Creates a Frame without a navigation listener attached.
-  virtual fuchsia::web::FramePtr CreateFrame();
 };
 
 // Base test class used for testing FrameImpl and the WebEngine Frame FIDL
@@ -38,10 +34,6 @@
   FrameImplTestBaseWithServer();
   ~FrameImplTestBaseWithServer() override = default;
 
-  // Creates a Frame with |navigation_listener_| attached.
-  fuchsia::web::FramePtr CreateFrame() override;
-
-  cr_fuchsia::TestNavigationListener navigation_listener_;
   net::test_server::EmbeddedTestServerHandle test_server_handle_;
 };
 
diff --git a/fuchsia/engine/browser/headless_browsertest.cc b/fuchsia/engine/browser/headless_browsertest.cc
index 5960af7..955b993 100644
--- a/fuchsia/engine/browser/headless_browsertest.cc
+++ b/fuchsia/engine/browser/headless_browsertest.cc
@@ -3,12 +3,12 @@
 // found in the LICENSE file.
 
 #include "base/auto_reset.h"
-#include "base/macros.h"
 #include "base/test/scoped_command_line.h"
 #include "content/public/test/browser_test.h"
 #include "fuchsia/base/test/frame_test_util.h"
 #include "fuchsia/base/test/test_navigation_listener.h"
 #include "fuchsia/engine/switches.h"
+#include "fuchsia/engine/test/frame_for_test.h"
 #include "fuchsia/engine/test/test_data.h"
 #include "fuchsia/engine/test/web_engine_browser_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -26,6 +26,9 @@
   }
   ~HeadlessTest() override = default;
 
+  HeadlessTest(const HeadlessTest&) = delete;
+  HeadlessTest& operator=(const HeadlessTest&) = delete;
+
  protected:
   void SetUp() override {
     command_line_.GetProcessCommandLine()->AppendSwitchNative(
@@ -34,59 +37,52 @@
     cr_fuchsia::WebEngineBrowserTest::SetUp();
   }
 
-  void SetUpOnMainThread() override {
-    frame_ = CreateFrame();
-    frame_->GetNavigationController(controller_.NewRequest());
-  }
-
-  // Creates a Frame with |navigation_listener_| attached.
-  //
-  fuchsia::web::FramePtr CreateFrame() {
-    return WebEngineBrowserTest::CreateFrame(&navigation_listener_);
-  }
-
-  fuchsia::web::FramePtr frame_;
-  fuchsia::web::NavigationControllerPtr controller_;
-  cr_fuchsia::TestNavigationListener navigation_listener_;
   base::test::ScopedCommandLine command_line_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(HeadlessTest);
 };
 
 IN_PROC_BROWSER_TEST_F(HeadlessTest, AnimationRunsWhenFrameAlreadyActive) {
   ASSERT_TRUE(embedded_test_server()->Start());
   const GURL kAnimationUrl(
       embedded_test_server()->GetURL("/css_animation.html"));
-  frame_->EnableHeadlessRendering();
-  cr_fuchsia::LoadUrlAndExpectResponse(
-      controller_.get(), fuchsia::web::LoadUrlParams(), kAnimationUrl.spec());
-  navigation_listener_.RunUntilUrlAndTitleEquals(kAnimationUrl,
-                                                 "animation finished");
+
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
+  frame->EnableHeadlessRendering();
+  cr_fuchsia::LoadUrlAndExpectResponse(frame.GetNavigationController(),
+                                       fuchsia::web::LoadUrlParams(),
+                                       kAnimationUrl.spec());
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kAnimationUrl,
+                                                        "animation finished");
 }
 
 IN_PROC_BROWSER_TEST_F(HeadlessTest, AnimationNeverRunsWhenInactive) {
   ASSERT_TRUE(embedded_test_server()->Start());
   const GURL kAnimationUrl(
       embedded_test_server()->GetURL("/css_animation.html"));
-  cr_fuchsia::LoadUrlAndExpectResponse(
-      controller_.get(), fuchsia::web::LoadUrlParams(), kAnimationUrl.spec());
-  navigation_listener_.RunUntilUrlAndTitleEquals(kAnimationUrl,
-                                                 "animation never started");
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
+  cr_fuchsia::LoadUrlAndExpectResponse(frame.GetNavigationController(),
+                                       fuchsia::web::LoadUrlParams(),
+                                       kAnimationUrl.spec());
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(
+      kAnimationUrl, "animation never started");
 }
 
 IN_PROC_BROWSER_TEST_F(HeadlessTest, ActivateFrameAfterDocumentLoad) {
   ASSERT_TRUE(embedded_test_server()->Start());
   const GURL kAnimationUrl(
       embedded_test_server()->GetURL("/css_animation.html"));
-  cr_fuchsia::LoadUrlAndExpectResponse(
-      controller_.get(), fuchsia::web::LoadUrlParams(), kAnimationUrl.spec());
-  navigation_listener_.RunUntilUrlAndTitleEquals(kAnimationUrl,
-                                                 "animation never started");
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
+  cr_fuchsia::LoadUrlAndExpectResponse(frame.GetNavigationController(),
+                                       fuchsia::web::LoadUrlParams(),
+                                       kAnimationUrl.spec());
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(
+      kAnimationUrl, "animation never started");
 
-  frame_->EnableHeadlessRendering();
-  navigation_listener_.RunUntilUrlAndTitleEquals(kAnimationUrl,
-                                                 "animation finished");
+  frame->EnableHeadlessRendering();
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kAnimationUrl,
+                                                        "animation finished");
 }
 
 IN_PROC_BROWSER_TEST_F(HeadlessTest, DeactivationPreventsFutureAnimations) {
@@ -95,17 +91,20 @@
       embedded_test_server()->GetURL("/css_animation.html"));
 
   // Activate the frame and load the page. The animation should run.
-  frame_->EnableHeadlessRendering();
-  cr_fuchsia::LoadUrlAndExpectResponse(
-      controller_.get(), fuchsia::web::LoadUrlParams(), kAnimationUrl.spec());
-  navigation_listener_.RunUntilUrlAndTitleEquals(kAnimationUrl,
-                                                 "animation finished");
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
+  frame->EnableHeadlessRendering();
+  cr_fuchsia::LoadUrlAndExpectResponse(frame.GetNavigationController(),
+                                       fuchsia::web::LoadUrlParams(),
+                                       kAnimationUrl.spec());
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kAnimationUrl,
+                                                        "animation finished");
 
   // Deactivate the page and reload it. The animation should no longer run.
-  frame_->DisableHeadlessRendering();
-  controller_->Reload(fuchsia::web::ReloadType::NO_CACHE);
-  navigation_listener_.RunUntilUrlAndTitleEquals(kAnimationUrl,
-                                                 "animation never started");
+  frame->DisableHeadlessRendering();
+  frame.GetNavigationController()->Reload(fuchsia::web::ReloadType::NO_CACHE);
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(
+      kAnimationUrl, "animation never started");
 }
 
 }  // namespace
diff --git a/fuchsia/engine/browser/media_browsertest.cc b/fuchsia/engine/browser/media_browsertest.cc
index dfc9d79..a2dbe73 100644
--- a/fuchsia/engine/browser/media_browsertest.cc
+++ b/fuchsia/engine/browser/media_browsertest.cc
@@ -14,6 +14,7 @@
 #include "fuchsia/base/test/frame_test_util.h"
 #include "fuchsia/base/test/test_navigation_listener.h"
 #include "fuchsia/engine/features.h"
+#include "fuchsia/engine/test/frame_for_test.h"
 #include "fuchsia/engine/test/test_data.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -44,13 +45,6 @@
     CHECK(embedded_test_server()->Start());
     cr_fuchsia::WebEngineBrowserTest::SetUpOnMainThread();
   }
-
-  // Creates a Frame with |navigation_listener_| attached.
-  fuchsia::web::FramePtr CreateFrame() {
-    return WebEngineBrowserTest::CreateFrame(&navigation_listener_);
-  }
-
-  cr_fuchsia::TestNavigationListener navigation_listener_;
 };
 
 using SoftwareOnlyDecodersEnabledTest = MediaTest;
@@ -104,15 +98,15 @@
   // TODO(crbug.com/1200314): Refactor these tests to use FrameForTest and
   // possibly to simplify the calls below since some of the details are not
   // interesting to the individual tests. In particular, has_user_activation is
-  // more relevant than speclific LoadUrlParams.
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  // more relevant than specific LoadUrlParams.
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "can play vp8: true");
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl,
+                                                        "can play vp8: true");
 }
 
 // Verify that a codec only supported by a software decoder is reported as not
@@ -121,14 +115,14 @@
                        CanPlayTypeSoftwareOnlyCodecIsFalse) {
   const GURL kUrl(embedded_test_server()->GetURL(kCanPlaySoftwareOnlyCodecUrl));
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "can play vp8: false");
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl,
+                                                        "can play vp8: false");
 }
 
 // Verify that a codec only supported by a software decoder is loaded if
@@ -137,14 +131,13 @@
                        PlaySoftwareOnlyCodecSucceeds) {
   const GURL kUrl(embedded_test_server()->GetURL(kLoadSoftwareOnlyCodecUrl));
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "loaded");
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl, "loaded");
 }
 
 // Verify that a codec only supported by a software decoder is not loaded if
@@ -153,14 +146,14 @@
                        LoadSoftwareOnlyCodecFails) {
   const GURL kUrl(embedded_test_server()->GetURL(kLoadSoftwareOnlyCodecUrl));
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "media element error");
+      frame.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      kUrl.spec()));
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl,
+                                                        "media element error");
 }
 
 // Verify that a codec supported by hardware and software decoders plays if
@@ -173,19 +166,17 @@
   const GURL kUrl(
       embedded_test_server()->GetURL(kLoadHardwareAndSoftwareCodecUrl));
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), cr_fuchsia::CreateLoadUrlParamsWithUserActivation(),
-      kUrl.spec()));
+      frame.GetNavigationController(),
+      cr_fuchsia::CreateLoadUrlParamsWithUserActivation(), kUrl.spec()));
 
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "loaded");
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl, "loaded");
   cr_fuchsia::ExecuteJavaScript(frame.get(), "bear.play()");
 
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "playing");
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl, "playing");
 }
 
 // Verify that a codec supported by hardware and software plays if
@@ -198,17 +189,15 @@
   const GURL kUrl(
       embedded_test_server()->GetURL(kLoadHardwareAndSoftwareCodecUrl));
 
-  fuchsia::web::FramePtr frame = CreateFrame();
-
-  fuchsia::web::NavigationControllerPtr controller;
-  frame->GetNavigationController(controller.NewRequest());
+  auto frame = cr_fuchsia::FrameForTest::Create(
+      context(), fuchsia::web::CreateFrameParams());
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller.get(), cr_fuchsia::CreateLoadUrlParamsWithUserActivation(),
-      kUrl.spec()));
+      frame.GetNavigationController(),
+      cr_fuchsia::CreateLoadUrlParamsWithUserActivation(), kUrl.spec()));
 
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "loaded");
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl, "loaded");
   cr_fuchsia::ExecuteJavaScript(frame.get(), "bear.play()");
 
-  navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "playing");
+  frame.navigation_listener().RunUntilUrlAndTitleEquals(kUrl, "playing");
 }
diff --git a/fuchsia/engine/browser/navigation_policy_browsertest.cc b/fuchsia/engine/browser/navigation_policy_browsertest.cc
index ff5dfd6..3b3bad13 100644
--- a/fuchsia/engine/browser/navigation_policy_browsertest.cc
+++ b/fuchsia/engine/browser/navigation_policy_browsertest.cc
@@ -11,6 +11,7 @@
 #include "fuchsia/engine/browser/fake_navigation_policy_provider.h"
 #include "fuchsia/engine/browser/frame_impl.h"
 #include "fuchsia/engine/browser/navigation_policy_handler.h"
+#include "fuchsia/engine/test/frame_for_test.h"
 #include "fuchsia/engine/test/test_data.h"
 #include "fuchsia/engine/test/web_engine_browser_test.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -37,31 +38,32 @@
   void SetUp() override { cr_fuchsia::WebEngineBrowserTest::SetUp(); }
 
   void SetUpOnMainThread() override {
-    frame_ptr_ =
-        cr_fuchsia::WebEngineBrowserTest::CreateFrame(&navigation_listener_);
-    frame_impl_ = context_impl()->GetFrameImplForTest(&frame_ptr_);
-    frame_ptr_->GetNavigationController(navigation_controller_.NewRequest());
+    frame_ = cr_fuchsia::FrameForTest::Create(
+        context(), fuchsia::web::CreateFrameParams());
+
+    // Spin the loop to allow the Create() request to be handled.
+    base::RunLoop().RunUntilIdle();
+    frame_impl_ = context_impl()->GetFrameImplForTest(&frame_.ptr());
+
     ASSERT_TRUE(embedded_test_server()->Start());
 
     // Register a NavigationPolicyProvider to the frame.
     fuchsia::web::NavigationPolicyProviderParams params;
     *params.mutable_main_frame_phases() = fuchsia::web::NavigationPhase::START;
     *params.mutable_subframe_phases() = fuchsia::web::NavigationPhase::REDIRECT;
-    frame_ptr_->SetNavigationPolicyProvider(
-        std::move(params), policy_provider_binding_.NewBinding());
+    frame_->SetNavigationPolicyProvider(std::move(params),
+                                        policy_provider_binding_.NewBinding());
     base::RunLoop().RunUntilIdle();
     ASSERT_TRUE(
         frame_impl_->navigation_policy_handler()->is_provider_connected());
   }
 
  protected:
-  fuchsia::web::FramePtr frame_ptr_;
-  FrameImpl* frame_impl_;
+  cr_fuchsia::FrameForTest frame_;
+  FrameImpl* frame_impl_ = nullptr;
   fidl::Binding<fuchsia::web::NavigationPolicyProvider>
       policy_provider_binding_;
   FakeNavigationPolicyProvider policy_provider_;
-  cr_fuchsia::TestNavigationListener navigation_listener_;
-  fuchsia::web::NavigationControllerPtr navigation_controller_;
 };
 
 IN_PROC_BROWSER_TEST_F(NavigationPolicyTest, Proceed) {
@@ -69,9 +71,9 @@
 
   GURL page_url(embedded_test_server()->GetURL(std::string(kPagePath)));
   ASSERT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      navigation_controller_.get(), fuchsia::web::LoadUrlParams(),
+      frame_.GetNavigationController(), fuchsia::web::LoadUrlParams(),
       page_url.spec()));
-  navigation_listener_.RunUntilUrlAndTitleEquals(page_url, kPageTitle);
+  frame_.navigation_listener().RunUntilUrlAndTitleEquals(page_url, kPageTitle);
 
   EXPECT_EQ(page_url.spec(), policy_provider_.requested_navigation()->url());
 }
@@ -84,7 +86,7 @@
   // Make sure the page has had time to load, but has not actually loaded, since
   // we cannot check for the absence of page data.
   ASSERT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      navigation_controller_.get(), fuchsia::web::LoadUrlParams(),
+      frame_.GetNavigationController(), fuchsia::web::LoadUrlParams(),
       page_url.spec()));
   base::RunLoop run_loop;
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
@@ -95,8 +97,8 @@
   // Make sure an up to date NavigationState is used.
   fuchsia::web::NavigationState state;
   state.set_url(page_url.spec());
-  navigation_listener_.RunUntilNavigationStateMatches(state);
-  auto* current_state = navigation_listener_.current_state();
+  frame_.navigation_listener().RunUntilNavigationStateMatches(state);
+  auto* current_state = frame_.navigation_listener().current_state();
   EXPECT_TRUE(current_state->has_is_main_document_loaded());
   EXPECT_FALSE(current_state->is_main_document_loaded());
 
diff --git a/fuchsia/engine/browser/permissions_browsertest.cc b/fuchsia/engine/browser/permissions_browsertest.cc
index 8c1bc85..0a0429f 100644
--- a/fuchsia/engine/browser/permissions_browsertest.cc
+++ b/fuchsia/engine/browser/permissions_browsertest.cc
@@ -8,7 +8,9 @@
 #include "content/public/test/browser_test.h"
 #include "fuchsia/base/mem_buffer_util.h"
 #include "fuchsia/base/test/frame_test_util.h"
+#include "fuchsia/base/test/test_navigation_listener.h"
 #include "fuchsia/engine/browser/frame_impl_browser_test_base.h"
+#include "fuchsia/engine/test/frame_for_test.h"
 #include "fuchsia/engine/test/test_data.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
@@ -25,7 +27,8 @@
 
   void SetUpOnMainThread() override {
     FrameImplTestBaseWithServer::SetUpOnMainThread();
-    frame_ = CreateFrame();
+    frame_ = cr_fuchsia::FrameForTest::Create(
+        context(), fuchsia::web::CreateFrameParams());
   }
 
   void GrantPermission(fuchsia::web::PermissionType type,
@@ -47,7 +50,7 @@
       const net::test_server::HttpRequest& request);
 
   uint64_t before_load_js_id_ = 1;
-  fuchsia::web::FramePtr frame_;
+  cr_fuchsia::FrameForTest frame_;
 };
 
 void PermissionsBrowserTest::InjectBeforeLoadJs(const std::string& code) {
@@ -82,7 +85,7 @@
 
   ASSERT_NO_FATAL_FAILURE(LoadPageInIframe(iframe_src.spec()));
 
-  navigation_listener_.RunUntilTitleEquals("ended");
+  frame_.navigation_listener().RunUntilTitleEquals("ended");
 }
 
 IN_PROC_BROWSER_TEST_F(PermissionsBrowserTest, NoPermissionInSameOriginIframe) {
@@ -93,7 +96,7 @@
 
   ASSERT_NO_FATAL_FAILURE(LoadPageInIframe(iframe_src.spec()));
 
-  navigation_listener_.RunUntilTitleEquals("ended-NotFoundError");
+  frame_.navigation_listener().RunUntilTitleEquals("ended-NotFoundError");
 }
 
 IN_PROC_BROWSER_TEST_F(PermissionsBrowserTest, PermissionInCrossOriginIframe) {
@@ -113,7 +116,7 @@
 
   ASSERT_NO_FATAL_FAILURE(LoadPageInIframe(iframe_src.spec()));
 
-  navigation_listener_.RunUntilTitleEquals("ended-NotAllowedError");
+  frame_.navigation_listener().RunUntilTitleEquals("ended-NotAllowedError");
 }
 
 IN_PROC_BROWSER_TEST_F(PermissionsBrowserTest,
@@ -140,5 +143,5 @@
 
   ASSERT_NO_FATAL_FAILURE(LoadPageInIframe(iframe_src.spec()));
 
-  navigation_listener_.RunUntilTitleEquals("ended");
+  frame_.navigation_listener().RunUntilTitleEquals("ended");
 }
diff --git a/fuchsia/engine/browser/theme_manager_browsertest.cc b/fuchsia/engine/browser/theme_manager_browsertest.cc
index 5df8332..f771221 100644
--- a/fuchsia/engine/browser/theme_manager_browsertest.cc
+++ b/fuchsia/engine/browser/theme_manager_browsertest.cc
@@ -7,7 +7,6 @@
 #include "base/fuchsia/scoped_service_binding.h"
 #include "base/fuchsia/test_component_context_for_process.h"
 #include "base/json/json_writer.h"
-#include "base/macros.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/stringprintf.h"
 #include "content/public/test/browser_test.h"
@@ -16,6 +15,7 @@
 #include "fuchsia/base/test/test_navigation_listener.h"
 #include "fuchsia/engine/browser/context_impl.h"
 #include "fuchsia/engine/browser/frame_impl.h"
+#include "fuchsia/engine/test/frame_for_test.h"
 #include "fuchsia/engine/test/test_data.h"
 #include "fuchsia/engine/test/web_engine_browser_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -46,20 +46,21 @@
     ASSERT_TRUE(embedded_test_server()->Start());
     cr_fuchsia::WebEngineBrowserTest::SetUpOnMainThread();
 
-    frame_ = WebEngineBrowserTest::CreateFrame(&navigation_listener_);
+    frame_ = cr_fuchsia::FrameForTest::Create(
+        context(), fuchsia::web::CreateFrameParams());
     base::RunLoop().RunUntilIdle();
-    frame_->GetNavigationController(controller_.NewRequest());
 
     const std::string kPageTitle = "title 1";
     const GURL kPageUrl = embedded_test_server()->GetURL("/title1.html");
 
-    cr_fuchsia::LoadUrlAndExpectResponse(
-        controller_.get(), fuchsia::web::LoadUrlParams(), kPageUrl.spec());
+    cr_fuchsia::LoadUrlAndExpectResponse(frame_.GetNavigationController(),
+                                         fuchsia::web::LoadUrlParams(),
+                                         kPageUrl.spec());
 
     fuchsia::web::NavigationState state;
     state.set_is_main_document_loaded(true);
     state.set_title(kPageTitle);
-    navigation_listener_.RunUntilNavigationStateMatches(state);
+    frame_.navigation_listener().RunUntilNavigationStateMatches(state);
   }
 
   // Reports the system |theme_type| via the Display FIDL service.
@@ -85,7 +86,9 @@
   // Returns the name of the color scheme selected by the CSS feature matcher.
   base::StringPiece QueryThemeFromCssFeature() {
     content::WebContents* web_contents =
-        context_impl()->GetFrameImplForTest(&frame_)->web_contents_for_test();
+        context_impl()
+            ->GetFrameImplForTest(&frame_.ptr())
+            ->web_contents_for_test();
 
     for (const char* scheme : {kCssDark, kCssLight}) {
       bool matches;
@@ -108,7 +111,7 @@
   bool SetTheme(fuchsia::settings::ThemeType theme) {
     frame_->SetPreferredTheme(theme);
     base::RunLoop().RunUntilIdle();
-    return frame_.is_bound();
+    return frame_.ptr().is_bound();
   }
 
  protected:
@@ -126,9 +129,7 @@
   absl::optional<base::TestComponentContextForProcess> component_context_;
   absl::optional<base::ScopedServiceBinding<fuchsia::settings::Display>>
       display_binding_;
-  cr_fuchsia::TestNavigationListener navigation_listener_;
-  fuchsia::web::NavigationControllerPtr controller_;
-  fuchsia::web::FramePtr frame_;
+  cr_fuchsia::FrameForTest frame_;
 
   base::OnceClosure on_watch_closure_;
   absl::optional<WatchCallback> watch_callback_;
@@ -168,7 +169,7 @@
   base::RunLoop().RunUntilIdle();
 
   ASSERT_FALSE(display_binding_);
-  ASSERT_FALSE(frame_);
+  ASSERT_FALSE(frame_.ptr());
 }
 
 // Verify that invalid values from the Display service, such as DEFAULT,
diff --git a/fuchsia/engine/test/web_engine_browser_test.cc b/fuchsia/engine/test/web_engine_browser_test.cc
index f4d192be..5232f43 100644
--- a/fuchsia/engine/test/web_engine_browser_test.cc
+++ b/fuchsia/engine/test/web_engine_browser_test.cc
@@ -44,10 +44,6 @@
   }
 }
 
-void WebEngineBrowserTest::TearDownOnMainThread() {
-  navigation_listener_bindings_.CloseAll();
-}
-
 void WebEngineBrowserTest::PostRunTestOnMainThread() {
   // Unbind the Context while the message loops are still alive.
   context_.Unbind();
@@ -75,30 +71,6 @@
   return *published_services_;
 }
 
-fuchsia::web::FramePtr WebEngineBrowserTest::CreateFrame(
-    fuchsia::web::NavigationEventListener* listener) {
-  return CreateFrameWithParams(listener, {});
-}
-
-fuchsia::web::FramePtr WebEngineBrowserTest::CreateFrameWithParams(
-    fuchsia::web::NavigationEventListener* listener,
-    fuchsia::web::CreateFrameParams params) {
-  fuchsia::web::FramePtr frame;
-
-  context_->CreateFrameWithParams(std::move(params), frame.NewRequest());
-
-  if (listener) {
-    frame->SetNavigationEventListener(
-        navigation_listener_bindings_.AddBinding(listener));
-  }
-
-  // Pump the messages so that the caller can use the Frame instance
-  // immediately after this function returns.
-  base::RunLoop().RunUntilIdle();
-
-  return frame;
-}
-
 void WebEngineBrowserTest::SetHeadlessInCommandLine(
     base::CommandLine* command_line) {
   command_line->AppendSwitchNative(switches::kOzonePlatform,
diff --git a/fuchsia/engine/test/web_engine_browser_test.h b/fuchsia/engine/test/web_engine_browser_test.h
index 0639345..450a95a9 100644
--- a/fuchsia/engine/test/web_engine_browser_test.h
+++ b/fuchsia/engine/test/web_engine_browser_test.h
@@ -6,7 +6,6 @@
 #define FUCHSIA_ENGINE_TEST_WEB_ENGINE_BROWSER_TEST_H_
 
 #include <fuchsia/web/cpp/fidl.h>
-#include <lib/fidl/cpp/binding_set.h>
 #include <memory>
 
 #include "base/files/file_path.h"
@@ -38,29 +37,12 @@
   // through its outgoing directory.
   sys::ServiceDirectory& published_services();
 
-  // Creates a Frame for this Context using default parameters.
-  // |listener|: If set, specifies the navigation listener for the Frame.
-  fuchsia::web::FramePtr CreateFrame(
-      fuchsia::web::NavigationEventListener* listener);
-
-  // Creates a Frame for this Context using non-default parameters.
-  // |listener|: If set, specifies the navigation listener for the Frame.
-  // |params|: The CreateFrameParams to use.
-  fuchsia::web::FramePtr CreateFrameWithParams(
-      fuchsia::web::NavigationEventListener* listener,
-      fuchsia::web::CreateFrameParams params);
-
   // Gets the client object for the Context service.
   fuchsia::web::ContextPtr& context() { return context_; }
 
   // Gets the underlying ContextImpl service instance.
   ContextImpl* context_impl() const;
 
-  fidl::BindingSet<fuchsia::web::NavigationEventListener>&
-  navigation_listener_bindings() {
-    return navigation_listener_bindings_;
-  }
-
   void SetHeadlessInCommandLine(base::CommandLine* command_line);
 
   void set_test_server_root(const base::FilePath& path) {
@@ -71,13 +53,10 @@
   void SetUp() override;
   void PreRunTestOnMainThread() override;
   void PostRunTestOnMainThread() override;
-  void TearDownOnMainThread() override;
 
  private:
   base::FilePath test_server_root_;
   fuchsia::web::ContextPtr context_;
-  fidl::BindingSet<fuchsia::web::NavigationEventListener>
-      navigation_listener_bindings_;
 
   // Client for the directory of services published by this browser process.
   std::shared_ptr<sys::ServiceDirectory> published_services_;
diff --git a/fuchsia/runners/cast/api_bindings_client_browsertest.cc b/fuchsia/runners/cast/api_bindings_client_browsertest.cc
index b22d50f7..428dcb4 100644
--- a/fuchsia/runners/cast/api_bindings_client_browsertest.cc
+++ b/fuchsia/runners/cast/api_bindings_client_browsertest.cc
@@ -17,6 +17,7 @@
 #include "fuchsia/base/test/frame_test_util.h"
 #include "fuchsia/base/test/result_receiver.h"
 #include "fuchsia/base/test/test_navigation_listener.h"
+#include "fuchsia/engine/test/frame_for_test.h"
 #include "fuchsia/engine/test/web_engine_browser_test.h"
 #include "fuchsia/runners/cast/api_bindings_client.h"
 #include "fuchsia/runners/cast/create_web_message.h"
@@ -34,6 +35,9 @@
 
   ~ApiBindingsClientTest() override = default;
 
+  ApiBindingsClientTest(const ApiBindingsClientTest&) = delete;
+  ApiBindingsClientTest& operator=(const ApiBindingsClientTest&) = delete;
+
   void SetUp() override { cr_fuchsia::WebEngineBrowserTest::SetUp(); }
 
  protected:
@@ -49,8 +53,8 @@
     run_loop.Run();
     ASSERT_TRUE(client_->HasBindings());
 
-    frame_ = WebEngineBrowserTest::CreateFrame(&navigation_listener_);
-    frame_->GetNavigationController(controller_.NewRequest());
+    frame_ = cr_fuchsia::FrameForTest::Create(
+        context(), fuchsia::web::CreateFrameParams());
     connector_ =
         std::make_unique<NamedMessagePortConnectorFuchsia>(frame_.get());
 
@@ -73,15 +77,11 @@
     client_.reset();
   }
 
-  fuchsia::web::FramePtr frame_;
+  cr_fuchsia::FrameForTest frame_;
   std::unique_ptr<NamedMessagePortConnectorFuchsia> connector_;
   FakeApiBindingsImpl api_service_;
   fidl::Binding<chromium::cast::ApiBindings> api_service_binding_;
   std::unique_ptr<ApiBindingsClient> client_;
-  cr_fuchsia::TestNavigationListener navigation_listener_;
-  fuchsia::web::NavigationControllerPtr controller_;
-
-  DISALLOW_COPY_AND_ASSIGN(ApiBindingsClientTest);
 };
 
 // Tests API registration, injection, and message IPC.
@@ -106,8 +106,9 @@
   // Navigate to a test page that makes use of the injected bindings.
   const GURL test_url = embedded_test_server()->GetURL("/echo.html");
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
-      controller_.get(), fuchsia::web::LoadUrlParams(), test_url.spec()));
-  navigation_listener_.RunUntilUrlEquals(test_url);
+      frame_.GetNavigationController(), fuchsia::web::LoadUrlParams(),
+      test_url.spec()));
+  frame_.navigation_listener().RunUntilUrlEquals(test_url);
 
   std::string connect_message;
   std::unique_ptr<cast_api_bindings::MessagePort> connect_port;
diff --git a/fuchsia/runners/cast/named_message_port_connector_fuchsia_browsertest.cc b/fuchsia/runners/cast/named_message_port_connector_fuchsia_browsertest.cc
index f5f485d..17db0b0 100644
--- a/fuchsia/runners/cast/named_message_port_connector_fuchsia_browsertest.cc
+++ b/fuchsia/runners/cast/named_message_port_connector_fuchsia_browsertest.cc
@@ -7,7 +7,6 @@
 #include "base/barrier_closure.h"
 #include "base/bind.h"
 #include "base/files/file_util.h"
-#include "base/macros.h"
 #include "base/path_service.h"
 #include "base/strings/string_piece.h"
 #include "components/cast/message_port/fuchsia/message_port_fuchsia.h"
@@ -18,6 +17,7 @@
 #include "fuchsia/base/test/frame_test_util.h"
 #include "fuchsia/base/test/result_receiver.h"
 #include "fuchsia/base/test/test_navigation_listener.h"
+#include "fuchsia/engine/test/frame_for_test.h"
 #include "fuchsia/engine/test/web_engine_browser_test.h"
 #include "fuchsia/runners/cast/create_web_message.h"
 #include "fuchsia/runners/cast/named_message_port_connector_fuchsia.h"
@@ -35,18 +35,24 @@
  public:
   NamedMessagePortConnectorFuchsiaTest() {
     set_test_server_root(base::FilePath("fuchsia/runners/cast/testdata"));
-    navigation_listener_.SetBeforeAckHook(base::BindRepeating(
-        &NamedMessagePortConnectorFuchsiaTest::OnBeforeAckHook,
-        base::Unretained(this)));
   }
 
   ~NamedMessagePortConnectorFuchsiaTest() override = default;
 
+  NamedMessagePortConnectorFuchsiaTest(
+      const NamedMessagePortConnectorFuchsiaTest&) = delete;
+  NamedMessagePortConnectorFuchsiaTest& operator=(
+      const NamedMessagePortConnectorFuchsiaTest&) = delete;
+
  protected:
   // BrowserTestBase implementation.
   void SetUpOnMainThread() override {
     cr_fuchsia::WebEngineBrowserTest::SetUpOnMainThread();
-    frame_ = WebEngineBrowserTest::CreateFrame(&navigation_listener_);
+    frame_ = cr_fuchsia::FrameForTest::Create(
+        context(), fuchsia::web::CreateFrameParams());
+    frame_.navigation_listener().SetBeforeAckHook(base::BindRepeating(
+        &NamedMessagePortConnectorFuchsiaTest::OnBeforeAckHook,
+        base::Unretained(this)));
     connector_ =
         std::make_unique<NamedMessagePortConnectorFuchsia>(frame_.get());
   }
@@ -75,11 +81,8 @@
   }
 
   std::unique_ptr<base::RunLoop> navigate_run_loop_;
-  fuchsia::web::FramePtr frame_;
+  cr_fuchsia::FrameForTest frame_;
   std::unique_ptr<NamedMessagePortConnectorFuchsia> connector_;
-  cr_fuchsia::TestNavigationListener navigation_listener_;
-
-  DISALLOW_COPY_AND_ASSIGN(NamedMessagePortConnectorFuchsiaTest);
 };
 
 IN_PROC_BROWSER_TEST_F(NamedMessagePortConnectorFuchsiaTest, EndToEnd) {
@@ -106,7 +109,7 @@
 
   EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
       controller.get(), fuchsia::web::LoadUrlParams(), test_url.spec()));
-  navigation_listener_.RunUntilUrlEquals(test_url);
+  frame_.navigation_listener().RunUntilUrlEquals(test_url);
 
   // The JS code in connector.html should connect to the port "echo".
   receive_port_run_loop.Run();