// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <optional>

#include "base/strings/stringprintf.h"
#include "base/test/bind.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/api/scripting/scripting_api.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ssl/https_upgrades_util.h"
#include "components/version_info/channel.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/api_test_utils.h"
#include "extensions/browser/background_script_executor.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_registrar.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/script_executor.h"
#include "extensions/common/features/feature_channel.h"
#include "extensions/common/utils/content_script_utils.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
#include "extensions/test/test_extension_dir.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
#include "pdf/buildflags.h"
#include "ui/base/window_open_disposition.h"
#include "url/gurl.h"

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/ui_test_utils.h"
#endif

#if BUILDFLAG(ENABLE_PDF)
#include "base/test/scoped_feature_list.h"
#include "pdf/pdf_features.h"
#endif  // BUILDFLAG(ENABLE_PDF)

namespace extensions {

namespace {

constexpr const char kSimulatedResourcePath[] = "/simulated-resource.html";

#if BUILDFLAG(ENABLE_EXTENSIONS)
// Returns the IDs of all divs in a page; used for testing script injections.
constexpr char kGetDivIds[] =
    R"(let childIds = [];
       for (const child of document.body.children)
         childIds.push(child.id);
       JSON.stringify(childIds.sort());)";
#endif

}  // namespace

class ScriptingAPITest : public ExtensionApiTest {
 public:
  ScriptingAPITest() = default;
  ScriptingAPITest(const ScriptingAPITest&) = delete;
  ScriptingAPITest& operator=(const ScriptingAPITest&) = delete;
  ~ScriptingAPITest() override = default;

  void SetUpOnMainThread() override {
    ExtensionApiTest::SetUpOnMainThread();
    controllable_http_response_.emplace(embedded_test_server(),
                                        kSimulatedResourcePath);
    host_resolver()->AddRule("*", "127.0.0.1");
    content::SetupCrossSiteRedirector(embedded_test_server());
    ASSERT_TRUE(StartEmbeddedTestServer());
  }

  void OpenURLInCurrentTab(const GURL& url) {
    content::WebContents* web_contents = GetActiveWebContents();
    ASSERT_TRUE(web_contents);
    // NavigateToURL() waits for the load to stop and verifies the navigation
    // succeeded.
    ASSERT_TRUE(NavigateToURL(web_contents, url));
    EXPECT_EQ(url, web_contents->GetLastCommittedURL());
  }

  void OpenURLInNewTab(const GURL& url) {
    content::TestNavigationObserver nav_observer(url);
    nav_observer.StartWatchingNewWebContents();
    NavigateToURLInNewTab(url);
    nav_observer.Wait();
    auto* web_contents = GetActiveWebContents();
    content::WaitForLoadStop(web_contents);
    EXPECT_TRUE(nav_observer.last_navigation_succeeded());
    EXPECT_EQ(url, web_contents->GetLastCommittedURL());
  }

  net::test_server::ControllableHttpResponse& controllable_http_response() {
    return *controllable_http_response_;
  }

 private:
  // A controllable HTTP response for tests that need fine-grained timing.
  // Must be constructed as part of the test suite because it needs to
  // happen before the embedded test server is initialized.
  std::optional<net::test_server::ControllableHttpResponse>
      controllable_http_response_;
};

IN_PROC_BROWSER_TEST_F(ScriptingAPITest, GetContentScripts) {
  ASSERT_TRUE(RunExtensionTest("scripting/get_scripts")) << message_;
}

IN_PROC_BROWSER_TEST_F(ScriptingAPITest, MainFrameTests) {
  OpenURLInCurrentTab(embedded_test_server()->GetURL(
      "example.com", "/extensions/main_world_script_flag.html"));
  OpenURLInNewTab(
      embedded_test_server()->GetURL("chromium.org", "/title2.html"));

  ASSERT_TRUE(RunExtensionTest("scripting/main_frame", {},
                               {.ignore_manifest_warnings = true}))
      << message_;
}

IN_PROC_BROWSER_TEST_F(ScriptingAPITest, SubFramesTests) {
  OpenURLInCurrentTab(
      embedded_test_server()->GetURL("a.com", "/iframe_cross_site.html"));
  OpenURLInNewTab(
      embedded_test_server()->GetURL("d.com", "/iframe_cross_site.html"));
  OpenURLInNewTab(
      embedded_test_server()->GetURL("e.com", "/iframe_sandboxed_srcdoc.html"));
  OpenURLInNewTab(
      embedded_test_server()->GetURL("f.com", "/iframe_blob_url.html"));

  ASSERT_TRUE(RunExtensionTest("scripting/sub_frames")) << message_;
}

// Test validating we don't insert content into nested WebContents.
IN_PROC_BROWSER_TEST_F(ScriptingAPITest, NestedWebContents) {
  OpenURLInCurrentTab(
      embedded_test_server()->GetURL("a.com", "/iframe_about_blank.html"));

  content::RenderFrameHost* iframe_host =
      content::ChildFrameAt(GetActiveWebContents(), 0);
  ASSERT_TRUE(iframe_host);
  content::WebContents* inner_web_contents =
      content::CreateAndAttachInnerContents(iframe_host);

  EXPECT_TRUE(content::NavigateToURL(
      inner_web_contents, embedded_test_server()->GetURL("/title1.html")));

  // From there, the test continues in the JS.
  ASSERT_TRUE(RunExtensionTest("scripting/nested_web_contents")) << message_;
}

#if BUILDFLAG(ENABLE_PDF)
class ScriptingAPIOopifPdfTest : public ScriptingAPITest {
 public:
  ScriptingAPIOopifPdfTest() {
    feature_list_.InitAndEnableFeature(chrome_pdf::features::kPdfOopif);
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

// Validate that extensions are not allowed to execute scripts within the PDF
// extension frame and the PDF content frame.
IN_PROC_BROWSER_TEST_F(ScriptingAPIOopifPdfTest, PdfFrames) {
  OpenURLInCurrentTab(
      embedded_test_server()->GetURL("a.com", "/page_with_embedded_pdf.html"));

  // From there, the test continues in the JS.
  ASSERT_TRUE(RunExtensionTest("scripting/pdf")) << message_;
}
#endif  // BUILDFLAG(ENABLE_PDF)

IN_PROC_BROWSER_TEST_F(ScriptingAPITest, CSSInjection) {
  OpenURLInCurrentTab(
      embedded_test_server()->GetURL("example.com", "/simple.html"));
  OpenURLInNewTab(
      embedded_test_server()->GetURL("chromium.org", "/title2.html"));
  OpenURLInNewTab(embedded_test_server()->GetURL("subframes.example",
                                                 "/iframe_cross_site.html"));
  OpenURLInNewTab(embedded_test_server()->GetURL(
      "subframes-sandboxed.example", "/iframe_sandboxed_srcdoc.html"));

  ASSERT_TRUE(RunExtensionTest("scripting/css_injection")) << message_;
}

IN_PROC_BROWSER_TEST_F(ScriptingAPITest, CSSRemoval) {
  ASSERT_TRUE(RunExtensionTest("scripting/remove_css")) << message_;
}

IN_PROC_BROWSER_TEST_F(ScriptingAPITest, RegisterContentScripts) {
  ASSERT_TRUE(RunExtensionTest("scripting/register_scripts")) << message_;
}

IN_PROC_BROWSER_TEST_F(ScriptingAPITest, UnregisterContentScripts) {
  ASSERT_TRUE(RunExtensionTest("scripting/unregister_scripts")) << message_;
}

IN_PROC_BROWSER_TEST_F(ScriptingAPITest, UpdateContentScripts) {
  ASSERT_TRUE(RunExtensionTest("scripting/update_scripts")) << message_;
}

IN_PROC_BROWSER_TEST_F(ScriptingAPITest, DynamicContentScriptParameters) {
  // Dynamic content script parameters are currently limited to trunk.
  ScopedCurrentChannel scoped_channel(version_info::Channel::UNKNOWN);
  ASSERT_TRUE(RunExtensionTest("scripting/dynamic_script_parameters"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(ScriptingAPITest, DynamicContentScriptsMainWorld) {
  ASSERT_TRUE(RunExtensionTest("scripting/dynamic_scripts_main_world"))
      << message_;
}

// Unregisters a pending script and verifies that the script is unregistered
// and doesn't inject.
// Regression test for https://crbug.com/1496907.
IN_PROC_BROWSER_TEST_F(ScriptingAPITest,
                       RapidDynamicContentScriptRegistrationAndUnregistration) {
  static constexpr char kManifest[] =
      R"({
           "name": "test",
           "manifest_version": 3,
           "version": "0.1",
           "background": {"service_worker": "background.js"},
           "permissions": ["scripting"],
           "host_permissions": ["*://example.com/*"]
         })";
  static constexpr char kBackgroundJs[] =
      R"(chrome.test.runTests([
           async function registerScripts() {
             const scripts =
                 [
                   {
                     id: 'script_1',
                     matches: ['http://example.com/*'],
                     js: ['script1.js'],
                     runAt: 'document_end',
                   },
                   {
                     id: 'script_2',
                     matches: ['http://example.com/*'],
                     js: ['script2.js'],
                     runAt: 'document_end',
                   }
                 ];

             // Call to register the two scripts, then immediately (before
             // registration is complete) unregister script 1.
             const registered =
                 chrome.scripting.registerContentScripts(scripts);
             const unregistered =
                 chrome.scripting.unregisterContentScripts({ids: ['script_1']});
             await Promise.allSettled([registered, unregistered]);

             // Only script 2 should still be registered.
             const registeredScripts =
                 await chrome.scripting.getRegisteredContentScripts();
             chrome.test.assertEq(['script_2'],
                                  registeredScripts.map(script => script.id));

             chrome.test.succeed();
         }]);)";
  static constexpr char kScript1Js[] =
      R"(var div = document.createElement('div');
         div.id = 'injected_1';
         document.body.appendChild(div);)";
  static constexpr char kScript2Js[] =
      R"(console.warn('injectory');var div = document.createElement('div');
         div.id = 'injected_2';
         document.body.appendChild(div);)";

  TestExtensionDir test_dir;
  test_dir.WriteManifest(kManifest);
  test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), kBackgroundJs);
  test_dir.WriteFile(FILE_PATH_LITERAL("script1.js"), kScript1Js);
  test_dir.WriteFile(FILE_PATH_LITERAL("script2.js"), kScript2Js);

  // The extension registers two scripts and then immediately unregistered
  // the first; it also verifies the API indicates only the second script
  // is still registered.
  ResultCatcher result_catcher;
  const Extension* extension = LoadExtension(test_dir.UnpackedPath());
  ASSERT_TRUE(extension);
  ASSERT_TRUE(result_catcher.GetNextResult()) << result_catcher.message();

  // Verify that only the second script injects (i.e., that the first script
  // really was unregistered). Regression test for https://crbug.com/1496907.
  auto* web_contents = GetActiveWebContents();
  const GURL url =
      embedded_test_server()->GetURL("example.com", "/simple.html");
  ASSERT_TRUE(NavigateToURL(web_contents, url));
  content::RenderFrameHost* new_frame = web_contents->GetPrimaryMainFrame();

  static constexpr char kGetInjectedIds[] =
      R"(const divs = document.body.getElementsByTagName('div');
         JSON.stringify(Array.from(divs).map(div => div.id));)";

  EXPECT_EQ(R"(["injected_2"])", content::EvalJs(new_frame, kGetInjectedIds));
}

#if BUILDFLAG(ENABLE_EXTENSIONS)
// Test that if an extension with persistent scripts is quickly unloaded while
// these scripts are being fetched, requests that wait on that extension's
// script load will be unblocked. Regression for crbug.com/1250575
// TODO(crbug.com/40282331): Disabled on ASAN due to leak caused by renderer gin
// objects which are intended to be leaked.
#if defined(ADDRESS_SANITIZER)
#define MAYBE_RapidLoadUnload DISABLED_RapidLoadUnload
#else
#define MAYBE_RapidLoadUnload RapidLoadUnload
#endif
IN_PROC_BROWSER_TEST_F(ScriptingAPITest, MAYBE_RapidLoadUnload) {
  ResultCatcher result_catcher;
  const Extension* extension = LoadExtension(
      test_data_dir_.AppendASCII("scripting/register_one_script"));
  ASSERT_TRUE(extension);
  EXPECT_TRUE(result_catcher.GetNextResult()) << result_catcher.message();

  DisableExtension(extension->id());

  // Load another extension with a content script that is injected into all
  // sites. This extension is necessary because while the register_one_script
  // extension is loading its scripts, requests which match ANY extension's
  // scripts are throttled. When an extension unloads before its script load is
  // finished and there are no more loads in progress, we want to verify that
  // ALL throttled requests are resumed, not just the ones matching the unloaded
  // extension's scripts.
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("content_scripts/css_injection")));

  // First, trigger an OnLoaded event for `extension`, then quickly trigger an
  // OnUnloaded event by calling Enable/DisableExtension. Since `extension`
  // contains persistent dynamic scripts, it must fetch them from the StateStore
  // which yields control of the thread so TriggerOnUnloaded is called
  // immediately, which unloads the extension before the Statestore fetch can
  // finish.
  extension_registrar()->EnableExtension(extension->id());
  extension_registrar()->DisableExtension(
      extension->id(), {disable_reason::DISABLE_USER_ACTION});

  // Verify that the navigation to google.com, which matches a script in the
  // css_injection extension, will complete.
  OpenURLInCurrentTab(
      embedded_test_server()->GetURL("google.com", "/simple.html"));
}

IN_PROC_BROWSER_TEST_F(ScriptingAPITest, DynamicContentScriptsSizeLimits) {
  auto single_scripts_limit_reset =
      script_parsing::CreateScopedMaxScriptLengthForTesting(700u);
  auto extension_scripts_limit_reset =
      script_parsing::CreateScopedMaxScriptsLengthPerExtensionForTesting(1200u);
  ASSERT_TRUE(RunExtensionTest("scripting/dynamic_scripts_size_limits"))
      << message_;
}

// Tests that scripting.executeScript called with files exceeding the max size
// limit will return an error and not execute.
IN_PROC_BROWSER_TEST_F(ScriptingAPITest, ExecuteScriptSizeLimit) {
  auto single_scripts_limit_reset =
      script_parsing::CreateScopedMaxScriptLengthForTesting(700u);
  ASSERT_TRUE(RunExtensionTest("scripting/execute_script_size_limit"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(ScriptingAPITest, ExecuteScriptSpecialCharacters) {
  ASSERT_TRUE(RunExtensionTest("scripting/execute_script_special_characters"))
      << message_;
}

// Tests that calling scripting.executeScript works on a newly created tab
// before the initial commit has happened. Regression for crbug.com/1191971.
// TODO(crbug.com/391921606): Port to desktop Android when we have test
// navigation utilities that support "wait for tab".
IN_PROC_BROWSER_TEST_F(ScriptingAPITest, ExecuteScriptBeforeInitialCommit) {
  constexpr char kManifest[] =
      R"({
           "name": "Scripting API Test",
           "manifest_version": 3,
           "version": "0.1",
           "permissions": ["scripting", "tabs"],
           "host_permissions": ["http://example.com/*"]
         })";

  constexpr char kArgTemplate[] =
      R"([{
            "target": {"tabId": %d},
            "func": "() => {
                document.title = 'Modified Title';
                return document.title;
            }"
          }])";

  TestExtensionDir test_dir;
  test_dir.WriteManifest(kManifest);

  {
    GURL target_url =
        embedded_test_server()->GetURL("example.com", "/simple.html");
    auto execute_script_function =
        base::MakeRefCounted<ScriptingExecuteScriptFunction>();

    const Extension* extension = LoadExtension(test_dir.UnpackedPath());
    ASSERT_TRUE(extension);
    execute_script_function->set_extension(extension);
    execute_script_function->set_has_callback(true);

    // We only want to wait for the tab to have loaded here and not for the
    // navigation to have ended because we want executeScript to run before the
    // navigation has committed.
    ui_test_utils::NavigateToURLWithDisposition(
        browser(), target_url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
        ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    ASSERT_TRUE(web_contents);
    EXPECT_TRUE(web_contents->GetLastCommittedURL().is_empty());
    EXPECT_EQ(target_url, web_contents->GetVisibleURL());

    // To avoid as much async delay as possible we invoke the execute script
    // extension function manually rather than calling it in JS.
    int tab_id = ExtensionTabUtil::GetTabId(web_contents);
    std::string args = base::StringPrintf(kArgTemplate, tab_id);
    std::optional<base::Value> result =
        api_test_utils::RunFunctionAndReturnSingleResult(
            execute_script_function.get(), args, profile());

    // Now we check the function call returned what we expected in the result.
    ASSERT_TRUE(result);
    base::Value::List& result_list = result->GetList();
    ASSERT_EQ(1u, result_list.size());
    const std::string* result_returned =
        result_list[0].GetDict().FindString("result");
    ASSERT_TRUE(result_returned);
    EXPECT_EQ("Modified Title", *result_returned);

    // We also check that the tab itself was modified by the call.
    EXPECT_EQ(u"Modified Title", web_contents->GetTitle());

    // Ensure that once the page has entirely finished loading and the
    // navigation has committed, our executeScript changes have stuck.
    EXPECT_TRUE(WaitForLoadStop(web_contents));
    EXPECT_EQ(target_url, web_contents->GetLastCommittedURL());
    EXPECT_EQ(u"Modified Title", web_contents->GetTitle());
  }

  // Same as above, but for a page which the extension does not have access to.
  {
    GURL target_url =
        embedded_test_server()->GetURL("noAccess.com", "/simple.html");
    auto execute_script_function =
        base::MakeRefCounted<ScriptingExecuteScriptFunction>();

    const Extension* extension = LoadExtension(test_dir.UnpackedPath());
    ASSERT_TRUE(extension);
    execute_script_function->set_extension(extension);
    execute_script_function->set_has_callback(true);

    // We only want to wait for the tab to have loaded here and not for the
    // navigation to have ended because we want executeScript to run before the
    // navigation has committed.
    ui_test_utils::NavigateToURLWithDisposition(
        browser(), target_url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
        ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    ASSERT_TRUE(web_contents);
    EXPECT_TRUE(web_contents->GetLastCommittedURL().is_empty());
    EXPECT_EQ(target_url, web_contents->GetVisibleURL());

    // To avoid as much async delay as possible we invoke the execute script
    // extension function manually rather than calling it in JS.
    int tab_id = ExtensionTabUtil::GetTabId(web_contents);
    std::string args = base::StringPrintf(kArgTemplate, tab_id);
    std::string error(api_test_utils::RunFunctionAndReturnError(
        execute_script_function.get(), args, profile()));

    // We should have gotten back an error that the page could not be accessed.
    // The URL for the pending navigation will be included because the extension
    // has the tabs persmission.
    std::string expected_error = base::StringPrintf(
        "Cannot access contents of url \"%s\". Extension manifest must request "
        "permission to access this host.",
        target_url.spec().c_str());
    EXPECT_EQ(expected_error, error);

    // We also need to verify the page was not modified by the execute script
    // call. Since this is a still loading page the title will be blank.
    EXPECT_EQ(u"", web_contents->GetTitle());

    // After the page has finished loading, there should be a title that is
    // still unmodified by our executeScript call.
    EXPECT_TRUE(WaitForLoadStop(web_contents));
    EXPECT_EQ(target_url, web_contents->GetLastCommittedURL());
    EXPECT_EQ(u"OK", web_contents->GetTitle());
  }
}

// Tests that extensions are able to specify that a script should be able to
// inject into a page as soon as possible. The testing for this is a bit tricky
// because we need to craft a page that is guaranteed to not load by the time
// the injections are triggered.
// TODO(crbug.com/391921606): Port to desktop Android when we have test
// navigation utilities that support "wait for tab".
IN_PROC_BROWSER_TEST_F(ScriptingAPITest, InjectImmediately) {
  static constexpr char kManifest[] =
      R"({
           "name": "Scripting Extension",
           "manifest_version": 3,
           "version": "0.1",
           "background": {"service_worker": "worker.js"},
           "permissions": ["scripting"],
           "host_permissions": ["http://example.com/*"]
         })";
  static constexpr char kWorker[] = "// Intentionally blank";

  TestExtensionDir test_dir;
  test_dir.WriteManifest(kManifest);
  test_dir.WriteFile(FILE_PATH_LITERAL("worker.js"), kWorker);
  const Extension* extension = LoadExtension(test_dir.UnpackedPath());
  ASSERT_TRUE(extension);

  // Navigate to a URL with a controllable response. This allows us to guarantee
  // that the page hasn't finished loading by the time we try to inject.
  const GURL page_url =
      embedded_test_server()->GetURL("example.com", kSimulatedResourcePath);
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), page_url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
  controllable_http_response().WaitForRequest();

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(web_contents->IsLoading());
  const int tab_id = ExtensionTabUtil::GetTabId(web_contents);

  // A script to call executeScript() twice - once with the default injection
  // timing and once with `injectImmediately` specified. The script with
  // `injectImmediately` should inject before the page finishes loading.
  // Upon injection completion, stores the result of the injection (which is the
  // target's URL) and sends a message.
  static constexpr char kInjectScripts[] =
      R"(function injectImmediate() {
           return 'Immediate: ' + window.location.href;
         }

         function injectDefault() {
           return 'Default: ' + window.location.href;
         }

         self.defaultResult = 'unset';
         self.immediateResult = 'unset';

         const target = {tabId: %d};
         chrome.scripting.executeScript(
             {
               target: target,
               func: injectDefault,
             },
             (results) => {
               self.defaultResult = results[0].result;
               chrome.test.sendMessage('default complete');
             });

         chrome.scripting.executeScript(
             {
               target: target,
               func: injectImmediate,
               injectImmediately: true,
             },
             (results) => {
               self.immediateResult = results[0].result;
               chrome.test.sendMessage('immediate complete');
             });)";

  std::string expected_immediate_result = "Immediate: " + page_url.spec();
  std::string expected_default_result = "Default: " + page_url.spec();

  // A helper function to run the script in the worker context.
  auto run_script_in_worker = [this, extension](const std::string& script) {
    return BackgroundScriptExecutor::ExecuteScript(
        profile(), extension->id(), script,
        BackgroundScriptExecutor::ResultCapture::kSendScriptResult);
  };

  auto get_default_result = [run_script_in_worker]() {
    return run_script_in_worker(
        "chrome.test.sendScriptResult(self.defaultResult);");
  };
  auto get_immediate_result = [run_script_in_worker]() {
    return run_script_in_worker(
        "chrome.test.sendScriptResult(self.immediateResult);");
  };

  // Send back some HTML for the request (this can only be done once the
  // request is received via WaitForRequest(), above). This doesn't complete
  // the request; the request is considered ongoing until
  // ControllableHttpResponse::Done() is called.
  controllable_http_response().Send(net::HTTP_OK, "text/html",
                                    "<html>Hello, World!</html>");

  EXPECT_TRUE(web_contents->IsLoading());

  ExtensionTestMessageListener immediate_listener("immediate complete");
  ExtensionTestMessageListener default_listener("default complete");
  BackgroundScriptExecutor::ExecuteScriptAsync(
      profile(), extension->id(), base::StringPrintf(kInjectScripts, tab_id));

  // The script with immediate injection should finish (but it's still round
  // trips to the browser and renderer, so it won't be synchronous).
  ASSERT_TRUE(immediate_listener.WaitUntilSatisfied());

  // The web contents should still be loading. The immediate injection should
  // have finished properly, and the default injection should still be pending.
  EXPECT_TRUE(web_contents->IsLoading());
  EXPECT_FALSE(default_listener.was_satisfied());
  EXPECT_EQ(base::Value("unset"), get_default_result());
  EXPECT_EQ(base::Value(expected_immediate_result), get_immediate_result());

  // Finish loading the page by completing the HTTP response.
  controllable_http_response().Done();
  ASSERT_TRUE(content::WaitForLoadStop(web_contents));

  // The default injection should now be able to complete.
  ASSERT_TRUE(default_listener.WaitUntilSatisfied());

  EXPECT_EQ(base::Value(expected_default_result), get_default_result());
  EXPECT_EQ(base::Value(expected_immediate_result), get_immediate_result());
}
#endif

#if !BUILDFLAG(IS_ANDROID)
// Verifies dynamic scripts are properly injected in incognito.
// Regression test for https://crbug.com/1495191.
// TODO(crbug.com/40200835): Enable this test on Android once PRE_ steps work
// properly on that platform.
IN_PROC_BROWSER_TEST_F(ScriptingAPITest,
                       PRE_DynamicContentScriptsInjectInIncognito) {
  // TODO(crbug.com/40937027): Convert test to use HTTPS and then remove.
  ScopedAllowHttpForHostnamesForTesting allow_http({"example.com"},
                                                   profile()->GetPrefs());

  // Load up two extensions, one that's allowed in incognito and one that's
  // not.
  const Extension* incognito_allowed =
      LoadExtension(test_data_dir_.AppendASCII("scripting/incognito_allowed"),
                    {.allow_in_incognito = true});
  const Extension* incognito_disallowed = LoadExtension(
      test_data_dir_.AppendASCII("scripting/incognito_disallowed"),
      {.allow_in_incognito = false});
  ASSERT_TRUE(incognito_allowed);
  ASSERT_TRUE(incognito_disallowed);

  auto register_scripts = [this](const ExtensionId& extension_id) {
    ResultCatcher result_catcher;
    BackgroundScriptExecutor::ExecuteScriptAsync(profile(), extension_id,
                                                 "registerScript();");
    ASSERT_TRUE(result_catcher.GetNextResult()) << result_catcher.message();
  };

  // In each extension, register a script that will inject a div with a given
  // ID indicating if it injected.
  register_scripts(incognito_allowed->id());
  register_scripts(incognito_disallowed->id());

  // Navigate to a page in the on-the-record profile. Both extensions should
  // inject.
  auto* web_contents = GetActiveWebContents();
  const GURL page_url =
      embedded_test_server()->GetURL("example.com", "/simple.html");
  ASSERT_TRUE(NavigateToURL(web_contents, page_url));
  content::RenderFrameHost* regular_page = web_contents->GetPrimaryMainFrame();
  EXPECT_EQ(R"(["incognito-allowed","incognito-disallowed"])",
            content::EvalJs(regular_page, kGetDivIds));

  // Now, navigate to a page in incognito. Only the incognito-allowed extension
  // should inject.
  content::WebContents* incognito_web_contents =
      PlatformOpenURLOffTheRecord(profile(), page_url);
  content::WaitForLoadStop(incognito_web_contents);

  EXPECT_EQ(R"(["incognito-allowed"])",
            content::EvalJs(incognito_web_contents, kGetDivIds));
}

// TODO(crbug.com/40200835): Enable this test on Android once PRE_ steps work
// properly on that platform.
IN_PROC_BROWSER_TEST_F(ScriptingAPITest,
                       DynamicContentScriptsInjectInIncognito) {
  // TODO(crbug.com/40937027): Convert test to use HTTPS and then remove.
  ScopedAllowHttpForHostnamesForTesting allow_http({"example.com"},
                                                   profile()->GetPrefs());

  // Repeat the steps of navigating to an on-the-record and off-the-record page
  // to validate injection after a restart. This verifies the incognito bit
  // is properly set when restoring scripts after a restart.
  auto* web_contents = GetActiveWebContents();
  const GURL page_url =
      embedded_test_server()->GetURL("example.com", "/simple.html");
  ASSERT_TRUE(NavigateToURL(web_contents, page_url));
  content::RenderFrameHost* regular_page = web_contents->GetPrimaryMainFrame();
  EXPECT_EQ(R"(["incognito-allowed","incognito-disallowed"])",
            content::EvalJs(regular_page, kGetDivIds));

  content::WebContents* incognito_web_contents =
      PlatformOpenURLOffTheRecord(profile(), page_url);
  content::WaitForLoadStop(incognito_web_contents);

  EXPECT_EQ(R"(["incognito-allowed"])",
            content::EvalJs(incognito_web_contents, kGetDivIds));
}
#endif  // BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(ENABLE_EXTENSIONS)
// Base test fixture for tests spanning multiple sessions where a custom arg is
// set before the test is run.
class PersistentScriptingAPITest : public ScriptingAPITest {
 public:
  PersistentScriptingAPITest() = default;

  // ScriptingAPITest override.
  void SetUp() override {
    // Initialize the listener object here before calling SetUp. This avoids a
    // race condition where the extension loads (as part of browser startup) and
    // sends a message before a message listener in C++ has been initialized.

    listener_ = std::make_unique<ExtensionTestMessageListener>(
        "ready", ReplyBehavior::kWillReply);
    ScriptingAPITest::SetUp();
  }

  // Reset listener before the browser gets torn down.
  void TearDownOnMainThread() override {
    listener_.reset();
    ScriptingAPITest::TearDownOnMainThread();
  }

 protected:
  // Used to wait for results from extension tests. This is initialized before
  // the test is run which avoids a race condition where the extension is loaded
  // (as part of startup) and finishes its tests before the ResultCatcher is
  // created.
  ResultCatcher result_catcher_;

  // Used to wait for the extension to load and send a ready message so the test
  // can reply which the extension waits for to start its testing functions.
  // This ensures that the testing functions will run after the browser has
  // finished initializing.
  std::unique_ptr<ExtensionTestMessageListener> listener_;
};

// Tests that registered content scripts which persist across sessions behave as
// expected. The test is run across three sessions.
IN_PROC_BROWSER_TEST_F(PersistentScriptingAPITest,
                       PRE_PRE_PersistentDynamicContentScripts) {
  const Extension* extension = LoadExtension(
      test_data_dir_.AppendASCII("scripting/persistent_dynamic_scripts"));
  ASSERT_TRUE(extension);
  ASSERT_TRUE(listener_->WaitUntilSatisfied());
  listener_->Reply(
      testing::UnitTest::GetInstance()->current_test_info()->name());
  EXPECT_TRUE(result_catcher_.GetNextResult()) << result_catcher_.message();
}

IN_PROC_BROWSER_TEST_F(PersistentScriptingAPITest,
                       PRE_PersistentDynamicContentScripts) {
  ASSERT_TRUE(listener_->WaitUntilSatisfied());
  listener_->Reply(
      testing::UnitTest::GetInstance()->current_test_info()->name());
  EXPECT_TRUE(result_catcher_.GetNextResult()) << result_catcher_.message();
}

IN_PROC_BROWSER_TEST_F(PersistentScriptingAPITest,
                       PersistentDynamicContentScripts) {
  ASSERT_TRUE(listener_->WaitUntilSatisfied());
  listener_->Reply(
      testing::UnitTest::GetInstance()->current_test_info()->name());
  EXPECT_TRUE(result_catcher_.GetNextResult()) << result_catcher_.message();
}

class ScriptingAPIPrerenderingTest : public ScriptingAPITest {
 protected:
  ScriptingAPIPrerenderingTest() = default;
  ~ScriptingAPIPrerenderingTest() override = default;

 private:
  content::test::ScopedPrerenderFeatureList scoped_feature_list_;
};

// TODO(crbug.com/40857271): disabled due to flakiness.
IN_PROC_BROWSER_TEST_F(ScriptingAPIPrerenderingTest, DISABLED_Basic) {
  ASSERT_TRUE(RunExtensionTest("scripting/prerendering")) << message_;
}
#endif  // BUILDFLAG(ENABLE_EXTENSIONS)

}  // namespace extensions
