File: runtime_interactive_apitest.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (120 lines) | stat: -rw-r--r-- 5,164 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string_view>

#include "base/strings/stringprintf.h"
#include "base/test/values_test_util.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/extensions/extension_action_test_helper.h"
#include "components/version_info/channel.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/test/browser_test.h"
#include "extensions/browser/background_script_executor.h"
#include "extensions/browser/extension_api_frame_id_map.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_host_test_helper.h"
#include "extensions/browser/script_executor.h"
#include "extensions/test/test_extension_dir.h"

namespace extensions {

// A test suite for `runtime.getContexts()` tests that need to be run as
// interactive UI tests (e.g. due to requiring focus).
class RuntimeGetContextsInteractiveApiTest : public ExtensionApiTest {
 public:
  RuntimeGetContextsInteractiveApiTest() = default;
  RuntimeGetContextsInteractiveApiTest(
      const RuntimeGetContextsInteractiveApiTest&) = delete;
  RuntimeGetContextsInteractiveApiTest& operator=(
      const RuntimeGetContextsInteractiveApiTest&) = delete;
  ~RuntimeGetContextsInteractiveApiTest() override = default;

  // Runs `chrome.runtime.getContexts()` and returns the result as a
  // base::Value.
  base::Value GetContexts(const Extension& extension, std::string_view filter) {
    static constexpr char kScriptTemplate[] =
        R"((async () => {
             chrome.test.sendScriptResult(
                 await chrome.runtime.getContexts(%s));
           })();)";
    std::string script = base::StringPrintf(kScriptTemplate, filter.data());
    return BackgroundScriptExecutor::ExecuteScript(
        profile(), extension.id(), script,
        BackgroundScriptExecutor::ResultCapture::kSendScriptResult);
  }
};

// Tests retrieving popup contexts using `chrome.runtime.getContexts()`.
// This needs to run as an interactive ui test because extension popups are
// closed on focus loss.
IN_PROC_BROWSER_TEST_F(RuntimeGetContextsInteractiveApiTest, GetPopupContext) {
  static constexpr char kManifest[] =
      R"({
           "name": "Get Contexts",
           "version": "0.1",
           "manifest_version": 3,
           "background": {
             "service_worker": "background.js"
           },
           "action": { "default_popup": "popup.html" }
         })";
  TestExtensionDir test_dir;
  test_dir.WriteManifest(kManifest);
  test_dir.WriteFile(FILE_PATH_LITERAL("background.js"),
                     "// Intentionally blank");
  test_dir.WriteFile(FILE_PATH_LITERAL("popup.html"),
                     "<html>I'm a popup!</html>");
  const Extension* extension = LoadExtension(test_dir.UnpackedPath());
  ASSERT_TRUE(extension);

  std::unique_ptr<ExtensionActionTestHelper> toolbar_helper =
      ExtensionActionTestHelper::Create(browser());
  ExtensionHostTestHelper popup_waiter(profile(), extension->id());
  popup_waiter.RestrictToType(mojom::ViewType::kExtensionPopup);
  toolbar_helper->Press(extension->id());
  ExtensionHost* popup_host = popup_waiter.WaitForHostCompletedFirstLoad();

  content::RenderFrameHost* popup_frame =
      popup_host->web_contents()->GetPrimaryMainFrame();
  int expected_frame_id = ExtensionApiFrameIdMap::GetFrameId(popup_frame);
  std::string expected_context_id =
      ExtensionApiFrameIdMap::GetContextId(popup_frame).AsLowercaseString();
  std::string expected_document_id =
      ExtensionApiFrameIdMap::GetDocumentId(popup_frame).ToString();
  std::string expected_frame_url =
      extension->ResolveExtensionURL("popup.html").spec();
  std::string expected_origin = extension->origin().Serialize();

  // Query for popup-based contexts. There should only be one.
  base::Value background_contexts =
      GetContexts(*extension, R"({"contextTypes": ["POPUP"]})");

  // Verify the properties of the returned context.
  // NOTE: Currently, extension popups are considered to have a window ID of -1.
  // This makes sense (they aren't really "in" a window), but there's also a
  // good argument for using the window ID of the Browser they're anchored to.
  // We may want to revisit this in the future.
  static constexpr char kExpectedTemplate[] =
      R"([{
            "contextType": "POPUP",
            "contextId": "%s",
            "tabId": -1,
            "windowId": -1,
            "frameId": %d,
            "documentId": "%s",
            "documentUrl": "%s",
            "documentOrigin": "%s",
            "incognito": false
         }])";
  std::string expected =
      base::StringPrintf(kExpectedTemplate, expected_context_id.c_str(),
                         expected_frame_id, expected_document_id.c_str(),
                         expected_frame_url.c_str(), expected_origin.c_str());
  EXPECT_THAT(background_contexts, base::test::IsJson(expected));
}

}  // namespace extensions