File: show_promo_in_page_interactive_uitest.cc

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (150 lines) | stat: -rw-r--r-- 6,237 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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright 2024 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 <string>

#include "base/functional/bind.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_element_identifiers.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/user_education/show_promo_in_page.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/test/interaction/interactive_browser_test.h"
#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "components/user_education/common/help_bubble/help_bubble_params.h"
#include "components/webui/chrome_urls/pref_names.h"
#include "content/public/test/browser_test.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"

namespace {

constexpr char16_t kBubbleBodyText[] = u"bubble body";

// Gets a partially-filled params block with default values. You will still
// need to specify `target_url` and `callback`.
ShowPromoInPage::Params GetDefaultParams() {
  ShowPromoInPage::Params params;
  params.bubble_anchor_id = kWebUIIPHDemoElementIdentifier;
  params.bubble_arrow = user_education::HelpBubbleArrow::kBottomLeft;
  params.bubble_text = kBubbleBodyText;
  params.timeout_override_for_testing = base::Seconds(90);
  return params;
}

// Javascript that verifies that `el` is the active element in its document or
// shadow DOM. Returns the empty string on success, or an error message on
// failure.
constexpr char kExpectActiveJs[] = R"(
  (el) => {
    // Find the containing document or shadow DOM.
    let root = null;
    for (let parent = el; parent; parent = parent.parentNode) {
      if (parent instanceof Document || parent instanceof ShadowRoot) {
        root = parent;
        break;
      }
    }
    if (!root) {
      return 'Root not found.';
    }
    if (!root.activeElement) {
      return 'No active element.';
    }
    if (root.activeElement !== el) {
      return 'Active element is ' + root.activeElement.tagName + '#' +
          root.activeElement.id;
    }
    return '';
  }
)";

}  // namespace

using ShowPromoInPageBrowserTest = InteractiveBrowserTest;

IN_PROC_BROWSER_TEST_F(ShowPromoInPageBrowserTest, FocusesBrowserTabAndAnchor) {
  g_browser_process->local_state()->SetBoolean(
      chrome_urls::kInternalOnlyUisEnabled, true);
  auto params = GetDefaultParams();
  params.target_url = GURL(chrome::kChromeUIUserEducationInternalsURL);
  params.page_open_mode = user_education::PageOpenMode::kOverwriteActiveTab;
  // Set the alt text here and then check that aria-label matches.
  params.close_button_alt_text_id = IDS_CLOSE_PROMO;

  DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kBubbleIsVisible);
  DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kTabId);

  auto help_bubble_start_callback =
      base::BindOnce(base::IgnoreResult(&ShowPromoInPage::Start), browser(),
                     std::move(params));
  static const DeepQuery kPathToAnchor = {"user-education-internals",
                                          "#IPH_WebUiHelpBubbleTest"};
  static const DeepQuery kPathToHelpBubbleCloseButton = {
      "user-education-internals", "#IPH_WebUiHelpBubbleTest", "help-bubble",
      "#close"};
  StateChange bubble_is_visible;
  bubble_is_visible.event = kBubbleIsVisible;
  bubble_is_visible.where = kPathToHelpBubbleCloseButton;
  bubble_is_visible.type = StateChange::Type::kExists;
  RunTestSequence(
      InstrumentTab(kTabId),
      Do([this]() { browser()->window()->SetFocusToLocationBar(true); }),
      Do(std::move(help_bubble_start_callback)),
      WaitForWebContentsNavigation(
          kTabId, GURL(chrome::kChromeUIUserEducationInternalsURL)),
      WaitForStateChange(kTabId, bubble_is_visible),
      Log("If the CheckViewProperty() step below fails intermittently, then  "
          "there is a race condition and we should change it to a "
          "StateObserver."),

      CheckViewProperty(ContentsWebView::kContentsWebViewElementId,
                        &views::View::HasFocus, true),
      CheckJsResultAt(kTabId, kPathToAnchor, kExpectActiveJs, ""));
}

IN_PROC_BROWSER_TEST_F(ShowPromoInPageBrowserTest,
                       FocusesBrowserTabAndAnchorInSingletonTab) {
  g_browser_process->local_state()->SetBoolean(
      chrome_urls::kInternalOnlyUisEnabled, true);
  auto params = GetDefaultParams();
  params.target_url = GURL(chrome::kChromeUIUserEducationInternalsURL);
  params.page_open_mode = user_education::PageOpenMode::kSingletonTab;
  // Set the alt text here and then check that aria-label matches.
  params.close_button_alt_text_id = IDS_CLOSE_PROMO;

  DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kBubbleIsVisible);
  DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kTabId);

  auto help_bubble_start_callback =
      base::BindOnce(base::IgnoreResult(&ShowPromoInPage::Start), browser(),
                     std::move(params));
  static const DeepQuery kPathToAnchor = {"user-education-internals",
                                          "#IPH_WebUiHelpBubbleTest"};
  static const DeepQuery kPathToHelpBubbleCloseButton = {
      "user-education-internals", "#IPH_WebUiHelpBubbleTest", "help-bubble",
      "#close"};
  StateChange bubble_is_visible;
  bubble_is_visible.event = kBubbleIsVisible;
  bubble_is_visible.where = kPathToHelpBubbleCloseButton;
  bubble_is_visible.type = StateChange::Type::kExists;
  RunTestSequence(
      InstrumentNextTab(kTabId),
      Do([this]() { browser()->window()->SetFocusToLocationBar(true); }),
      Do(std::move(help_bubble_start_callback)),
      WaitForWebContentsNavigation(
          kTabId, GURL(chrome::kChromeUIUserEducationInternalsURL)),
      WaitForStateChange(kTabId, bubble_is_visible),
      Log("If the CheckViewProperty() step below fails intermittently, then  "
          "there is a race condition and we should change it to a "
          "StateObserver."),

      CheckViewProperty(ContentsWebView::kContentsWebViewElementId,
                        &views::View::HasFocus, true),
      CheckJsResultAt(kTabId, kPathToAnchor, kExpectActiveJs, ""));
}