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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
fuchsia_web / webengine / browser / popup_browsertest.cc [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "content/public/test/browser_test.h"
#include "fuchsia_web/common/test/frame_for_test.h"
#include "fuchsia_web/common/test/frame_test_util.h"
#include "fuchsia_web/common/test/test_navigation_listener.h"
#include "fuchsia_web/webengine/browser/frame_impl_browser_test_base.h"
namespace {
constexpr char kPage1Path[] = "/title1.html";
constexpr char kPage2Path[] = "/title2.html";
constexpr char kPage1Title[] = "title 1";
constexpr char kPopupParentPath[] = "/popup_parent.html";
constexpr char kPopupRedirectPath[] = "/popup_child.html";
constexpr char kPopupMultiplePath[] = "/popup_multiple.html";
constexpr char kChildQueryParamName[] = "child_url";
constexpr char kPopupChildFile[] = "popup_child.html";
constexpr char kAutoplayFileAndQuery[] =
"play_video.html?autoplay=1&codecs=vp8";
constexpr char kAutoPlayBlockedTitle[] = "blocked";
constexpr char kAutoPlaySuccessTitle[] = "playing";
class TestPopupListener : public fuchsia::web::PopupFrameCreationListener {
public:
TestPopupListener() = default;
~TestPopupListener() override = default;
TestPopupListener(const TestPopupListener&) = delete;
TestPopupListener& operator=(const TestPopupListener&) = delete;
void GetAndAckNextPopup(fuchsia::web::FramePtr* frame,
fuchsia::web::PopupFrameCreationInfo* creation_info) {
if (!frame_) {
base::RunLoop run_loop;
received_popup_callback_ = run_loop.QuitClosure();
run_loop.Run();
}
*frame = frame_.Bind();
*creation_info = std::move(creation_info_);
popup_ack_callback_();
popup_ack_callback_ = {};
}
private:
void OnPopupFrameCreated(fidl::InterfaceHandle<fuchsia::web::Frame> frame,
fuchsia::web::PopupFrameCreationInfo creation_info,
OnPopupFrameCreatedCallback callback) override {
creation_info_ = std::move(creation_info);
frame_ = std::move(frame);
popup_ack_callback_ = std::move(callback);
if (received_popup_callback_)
std::move(received_popup_callback_).Run();
}
fidl::InterfaceHandle<fuchsia::web::Frame> frame_;
fuchsia::web::PopupFrameCreationInfo creation_info_;
base::OnceClosure received_popup_callback_;
OnPopupFrameCreatedCallback popup_ack_callback_;
};
class PopupTest : public FrameImplTestBaseWithServer {
public:
PopupTest()
: popup_listener_binding_(&popup_listener_),
popup_nav_listener_binding_(&popup_nav_listener_) {}
~PopupTest() override = default;
PopupTest(const PopupTest&) = delete;
PopupTest& operator=(const PopupTest&) = delete;
protected:
// Builds a URL for the kPopupParentPath page to pop up a Frame with
// |child_file_and_query|. |child_file_and_query| may optionally include a
// query string.
GURL GetParentPageTestServerUrl(const char* child) const {
const std::string url = base::StringPrintf("%s?%s=%s", kPopupParentPath,
kChildQueryParamName, child);
return embedded_test_server()->GetURL(url);
}
// Loads a page that autoplays video in a popup, populates the popup_*
// members, and returns its URL.
GURL LoadAutoPlayingPageInPopup(
fuchsia::web::AutoplayPolicy autoplay_policy) {
GURL popup_parent_url = GetParentPageTestServerUrl(kAutoplayFileAndQuery);
GURL popup_child_url = embedded_test_server()->GetURL(
base::StringPrintf("/%s", kAutoplayFileAndQuery));
auto parent_frame = FrameForTest::Create(context(), {});
// Set `autoplay_policy` for the parent frame. It should be inherited by the
// popup.
fuchsia::web::ContentAreaSettings settings;
settings.set_autoplay_policy(autoplay_policy);
parent_frame->SetContentAreaSettings(std::move(settings));
parent_frame->SetPopupFrameCreationListener(
popup_listener_binding_.NewBinding());
EXPECT_TRUE(LoadUrlAndExpectResponse(parent_frame.GetNavigationController(),
{}, popup_parent_url.spec()));
fuchsia::web::PopupFrameCreationInfo popup_info;
popup_listener_.GetAndAckNextPopup(&popup_frame_, &popup_info);
EXPECT_EQ(popup_info.initial_url(), popup_child_url);
popup_frame_->SetNavigationEventListener2(
popup_nav_listener_binding_.NewBinding(), /*flags=*/{});
return popup_child_url;
}
fuchsia::web::FramePtr popup_frame_;
TestPopupListener popup_listener_;
fidl::Binding<fuchsia::web::PopupFrameCreationListener>
popup_listener_binding_;
TestNavigationListener popup_nav_listener_;
fidl::Binding<fuchsia::web::NavigationEventListener>
popup_nav_listener_binding_;
};
IN_PROC_BROWSER_TEST_F(PopupTest, PopupWindowRedirect) {
GURL popup_parent_url = GetParentPageTestServerUrl(kPopupChildFile);
GURL popup_child_url(embedded_test_server()->GetURL(kPopupRedirectPath));
GURL title1_url(embedded_test_server()->GetURL(kPage1Path));
auto frame = FrameForTest::Create(context(), {});
frame->SetPopupFrameCreationListener(popup_listener_binding_.NewBinding());
EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(), {},
popup_parent_url.spec()));
// Verify the popup's initial URL, "popup_child.html".
fuchsia::web::PopupFrameCreationInfo popup_info;
popup_listener_.GetAndAckNextPopup(&popup_frame_, &popup_info);
EXPECT_EQ(popup_info.initial_url(), popup_child_url);
// Verify that the popup eventually redirects to "title1.html".
popup_frame_->SetNavigationEventListener2(
popup_nav_listener_binding_.NewBinding(), /*flags=*/{});
popup_nav_listener_.RunUntilUrlAndTitleEquals(title1_url, kPage1Title);
}
IN_PROC_BROWSER_TEST_F(PopupTest, MultiplePopups) {
GURL popup_parent_url(embedded_test_server()->GetURL(kPopupMultiplePath));
GURL title1_url(embedded_test_server()->GetURL(kPage1Path));
GURL title2_url(embedded_test_server()->GetURL(kPage2Path));
auto frame = FrameForTest::Create(context(), {});
frame->SetPopupFrameCreationListener(popup_listener_binding_.NewBinding());
EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(), {},
popup_parent_url.spec()));
fuchsia::web::PopupFrameCreationInfo popup_info;
popup_listener_.GetAndAckNextPopup(&popup_frame_, &popup_info);
EXPECT_EQ(popup_info.initial_url(), title1_url);
popup_listener_.GetAndAckNextPopup(&popup_frame_, &popup_info);
EXPECT_EQ(popup_info.initial_url(), title2_url);
}
// Verifies that the child popup Frame has the same default CreateFrameParams as
// the parent Frame by verifying that autoplay is blocked in the child. This
// mostly verifies that AutoPlaySucceedsis actually modifies behavior.
IN_PROC_BROWSER_TEST_F(PopupTest,
PopupFrameHasSameContentAreaSettings_AutoplayBlocked) {
// Load the page and wait for the popup Frame to be created.
GURL popup_child_url = LoadAutoPlayingPageInPopup(
fuchsia::web::AutoplayPolicy::REQUIRE_USER_ACTIVATION);
// Verify that the child does not autoplay media.
popup_nav_listener_.RunUntilUrlAndTitleEquals(popup_child_url,
kAutoPlayBlockedTitle);
}
// Verifies that the child popup Frame has the same CreateFrameParams as the
// parent Frame by allowing autoplay in the parent's params and verifying that
// autoplay succeeds in the child.
IN_PROC_BROWSER_TEST_F(PopupTest,
PopupFrameHasSameContentAreaSettings_AutoplaySucceeds) {
// Load the page and wait for the popup Frame to be created.
GURL popup_child_url =
LoadAutoPlayingPageInPopup(fuchsia::web::AutoplayPolicy::ALLOW);
// Verify that the child autoplays media.
popup_nav_listener_.RunUntilUrlAndTitleEquals(popup_child_url,
kAutoPlaySuccessTitle);
}
} // namespace