blob: a4eec882b6aa5c628360126d37210e3b0e2b3eed [file] [log] [blame]
// Copyright 2025 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 <string_view>
#include "base/files/file_path.h"
#include "base/logging.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tab_ui_helper.h"
#include "chrome/test/interaction/interactive_browser_test.h"
#include "chrome/test/supervised_user/browser_user.h"
#include "chrome/test/supervised_user/family_live_test.h"
#include "components/signin/public/base/signin_switches.h"
#include "components/supervised_user/test_support/family_link_settings_state_management.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/interaction/element_identifier.h"
#include "ui/base/interaction/state_observer.h"
#include "url/gurl.h"
namespace supervised_user {
namespace {
// Unblocks rendering the youtube iframe.
constexpr std::string_view kYouTubeHostPattern = "*.youtube.com";
// Unblocks playing back the video
constexpr std::string_view kGoogleVideoHostPattern = "*.googlevideo.com";
// When this string is present in frame's HTML, it indicates that the
// interstitial is shown.
constexpr std::string_view kInterstitialBodyClass =
"supervised-user-verify-subframe";
// Returns true, when in the given `browser`, in a tab with title `tab_title`,
// there is a iframe with name `iframe_name` that displays the YouTube
// interstitial. Note that the interstitial's presence is validated by looking
// for a specific class in the inner HTML of the iframe rather than parsing the
// DOM structure.
bool IsYouTubeInterstitialDisplayedInIframe(Browser& browser,
std::u16string_view tab_title,
std::string_view iframe_name) {
content::WebContents* web_contents = nullptr;
TabStripModel* const tab_strip_model = browser.tab_strip_model();
for (int i = 0; i < tab_strip_model->GetTabCount(); ++i) {
const std::u16string wc_title = tab_strip_model->GetTabAtIndex(i)
->GetTabFeatures()
->tab_ui_helper()
->GetTitle();
if (wc_title == tab_title) {
web_contents = browser.GetTabStripModel()->GetWebContentsAt(i);
break;
}
}
CHECK(web_contents) << "Expected tab with supplied title";
content::RenderFrameHost* rfh = content::FrameMatchingPredicate(
web_contents->GetPrimaryPage(),
base::BindRepeating(&content::FrameMatchesName, iframe_name));
CHECK(rfh) << "Expected iframe with supplied name";
std::string innerHTML =
content::EvalJs(rfh, "document.documentElement.innerHTML")
.ExtractString();
return innerHTML.find(kInterstitialBodyClass) != std::string::npos;
}
// All tests in this unit are subject to flakiness because they interact with a
// system that can be externally modified during execution.
// TODO(crbug.com/301587955): Fix placement of supervised_user/e2e test files
// and their dependencies.
class KidsProfileUiTest
: public InteractiveFamilyLiveTest,
public testing::WithParamInterface<FamilyLiveTest::RpcMode> {
public:
KidsProfileUiTest()
: InteractiveFamilyLiveTest(
GetParam(),
/*extra_enabled_hosts=*/{kYouTubeHostPattern,
kGoogleVideoHostPattern}) {}
void SetUpOnMainThread() override {
InteractiveFamilyLiveTest::SetUpOnMainThread();
test_server_.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
CHECK(test_server_.Start());
LOG(INFO) << "Embedded test server is listening on "
<< test_server_.host_port_pair().ToString() << ".";
}
protected:
net::test_server::EmbeddedTestServer& TestServer() { return test_server_; }
private:
// Serves static page that embeds an arbitrary YouTube widget (actual video is
// irrelevant).
net::test_server::EmbeddedTestServer test_server_;
};
IN_PROC_BROWSER_TEST_P(KidsProfileUiTest, DisplayInterstitialInPendingState) {
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kYouTubeTab);
DEFINE_LOCAL_STATE_IDENTIFIER_VALUE(ui::test::PollingStateObserver<bool>,
kInterstitialDisplayed);
TurnOnSync();
child().SignOutFromWeb();
GURL url_with_youtube_iframes =
TestServer().GetURL("/supervised_user/with_embedded_youtube_videos.html");
Browser& child_browser = child().browser();
RunTestSequence(
AddInstrumentedTab(kYouTubeTab, url_with_youtube_iframes, std::nullopt,
&child().browser()),
// Refer to with_embedded_youtube_videos.html to get title and iframe
// names.
PollState(
kInterstitialDisplayed,
[&child_browser]() {
return IsYouTubeInterstitialDisplayedInIframe(
child_browser,
u"Supervised User test: page with embedded YouTube videos",
"iframe1");
}),
WaitForState(kInterstitialDisplayed, true));
}
INSTANTIATE_TEST_SUITE_P(
,
KidsProfileUiTest,
testing::Values(FamilyLiveTest::RpcMode::kProd,
FamilyLiveTest::RpcMode::kTestImpersonation),
[](const testing::TestParamInfo<FamilyLiveTest::RpcMode>& info) {
return ToString(info.param);
});
} // namespace
} // namespace supervised_user