diff --git a/browser/brave_ads/tabs/BUILD.gn b/browser/brave_ads/tabs/BUILD.gn index a13e89679af2..d9ca0686dc8d 100644 --- a/browser/brave_ads/tabs/BUILD.gn +++ b/browser/brave_ads/tabs/BUILD.gn @@ -35,22 +35,21 @@ source_set("tabs") { source_set("browser_tests") { testonly = true - sources = [ "ads_tab_helper_browsertest.cc" ] - - deps = [ - ":tabs", - "//brave/components/brave_ads/browser:test_support", - "//brave/components/brave_ads/core/public:headers", - "//brave/components/brave_rewards/common", - "//chrome/browser/ui", - "//net:test_support", - ] - - if (is_android) { - deps += [ "//chrome/test:test_support_ui_android" ] - } else { - deps += [ "//chrome/test:test_support_ui" ] + if (!is_android) { + sources = [ "ads_tab_helper_browsertest.cc" ] + + deps = [ + ":tabs", + "//brave/browser/brave_ads", + "//brave/components/brave_ads/browser:test_support", + "//brave/components/brave_ads/core/public:headers", + "//brave/components/brave_rewards/common", + "//chrome/browser/ui", + "//chrome/test:test_support", + "//chrome/test:test_support_ui", + "//net:test_support", + ] + + defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] } - - defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] } diff --git a/browser/brave_ads/tabs/ads_tab_helper_browsertest.cc b/browser/brave_ads/tabs/ads_tab_helper_browsertest.cc index b01e7d8bf48b..4cdadab70b6c 100644 --- a/browser/brave_ads/tabs/ads_tab_helper_browsertest.cc +++ b/browser/brave_ads/tabs/ads_tab_helper_browsertest.cc @@ -5,249 +5,931 @@ #include "brave/browser/brave_ads/tabs/ads_tab_helper.h" +#include +#include +#include +#include +#include + +#include "base/callback_list.h" +#include "base/check.h" +#include "base/files/file_path.h" +#include "base/functional/bind.h" +#include "base/memory/raw_ptr.h" +#include "base/notreached.h" #include "base/path_service.h" +#include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/strings/stringprintf.h" #include "base/test/gmock_callback_support.h" +#include "brave/browser/brave_ads/ads_service_factory.h" #include "brave/components/brave_ads/browser/ads_service_mock.h" #include "brave/components/brave_ads/core/public/prefs/pref_names.h" #include "brave/components/brave_rewards/common/pref_names.h" #include "brave/components/constants/brave_paths.h" +#include "build/build_config.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h" +#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ssl/cert_verifier_browser_test.h" +#include "chrome/browser/sessions/session_restore_test_helper.h" +#include "chrome/browser/sessions/session_restore_test_utils.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_commands.h" +#include "chrome/browser/ui/browser_tabstrip.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/chrome_test_utils.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/platform_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/keep_alive_registry/keep_alive_types.h" +#include "components/keep_alive_registry/scoped_keep_alive.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_service.h" +#include "components/sessions/content/session_tab_helper.h" +#include "components/sessions/core/session_id.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/media_player_id.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_mock_cert_verifier.h" #include "net/dns/mock_host_resolver.h" +#include "net/http/http_status_code.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" -// npm run test -- brave_browser_tests --filter=AdsTabHelperTest* +// npm run test -- brave_browser_tests --filter=BraveAds* namespace brave_ads { namespace { -using base::test::RunClosure; -using testing::_; -using testing::IsEmpty; -using testing::Not; - -constexpr char kUrlDomain[] = "example.com"; -constexpr char kUrlPath[] = "/brave_ads/basic_page.html"; -constexpr char kSinglePageApplicationUrlPath[] = +constexpr char kHostName[] = "brave.com"; + +constexpr char kHandleRequestUrlPath[] = "/handle_request"; +constexpr char kHttpStatusCodeQueryKey[] = "http_status_code"; + +constexpr char kMultiPageApplicationWebpage[] = + "/brave_ads/multi_page_application.html"; +constexpr char kMultiPageApplicationWebpageHtmlContent[] = + "\n Adventure " + "Awaits\n\n\n\n

Welcome to Your Adventure

\n " + "

\n Embark on a journey of learning and discovery. Each step you " + "take brings you closer to mastering new skills and\n achieving your " + "goals.\n

\n \n " + "
\n \"The only limit to our realization of tomorrow is our " + "doubts of today.\" - Franklin D. Roosevelt\n
\n \n \n \n " + "\n \n \n \n " + "\n \n \n \n \n \n \n " + "\n \n \n " + "
TaskStatus
Learn RustCompleted
Contribute to a GitHub " + "repositoryIn Progress
Build a mobile appPending
\n\n\n\n"; +constexpr char kMultiPageApplicationWebpageTextContent[] = + "Welcome to Your Adventure\n\nEmbark on a journey of learning and " + "discovery. Each step you take brings you closer to mastering new skills " + "and achieving your goals.\n\nExplore new programming " + "languages\nContribute to open-source projects\nDevelop innovative " + "applications\n\"The only limit to our realization of tomorrow is our " + "doubts of today.\" - Franklin D. Roosevelt\nTask\tStatus\nLearn " + "Rust\tCompleted\nContribute to a GitHub repository\tIn Progress\nBuild a " + "mobile app\tPending"; + +constexpr char kSinglePageApplicationWebpage[] = "/brave_ads/single_page_application.html"; -constexpr char k500ErrorPagePath[] = "/500_error_page.html"; -constexpr char k404ErrorPagePath[] = "/404_error_page.html"; - -AdsTabHelper* GetActiveAdsTabHelper(Browser* browser) { - auto* web_contents = browser->tab_strip_model()->GetActiveWebContents(); - return AdsTabHelper::FromWebContents(web_contents); +constexpr char kSinglePageApplicationWebpageHtmlContent[] = + "\n Single Page Application\n " + "\n\n\n\n

same_document

\n \n\n\n\n"; +constexpr char kSinglePageApplicationClickSelectors[] = + "[data-navigation-type='same_document']"; + +constexpr char kAutoplayVideoWebpage[] = "/brave_ads/autoplay_video.html"; +constexpr char kVideoWebpage[] = "/brave_ads/video.html"; +constexpr char kVideoJavascriptDocumentQuerySelectors[] = "video"; + +MATCHER_P(FileName, filename, "") { + return arg.ExtractFileName() == filename; } +class MediaWaiter : public content::WebContentsObserver { + public: + explicit MediaWaiter(content::WebContents* const web_contents) + : content::WebContentsObserver(web_contents) {} + + void WaitForMediaStartedPlaying() { media_started_playing_run_loop_.Run(); } + + void WaitForMediaDestroyed() { media_destroyed_run_loop_.Run(); } + + void WaitForMediaSessionCreated() { media_session_created_run_loop_.Run(); } + + // content::WebContentsObserver: + void MediaStartedPlaying(const MediaPlayerInfo& /*video_type*/, + const content::MediaPlayerId& id) override { + id_ = id; + media_started_playing_run_loop_.Quit(); + } + + void MediaDestroyed(const content::MediaPlayerId& id) override { + EXPECT_EQ(id, id_); + media_destroyed_run_loop_.Quit(); + } + + void MediaSessionCreated( + content::MediaSession* const /*media_session*/) override { + media_session_created_run_loop_.Quit(); + } + + private: + std::optional id_; + + base::RunLoop media_started_playing_run_loop_; + base::RunLoop media_destroyed_run_loop_; + base::RunLoop media_session_created_run_loop_; +}; + } // namespace -class AdsTabHelperTest : public CertVerifierBrowserTest { +// We expect `is_visible=true` if both the browser and tab are active, and +// `is_visible=false` if either the browser or tab is inactive. To avoid flaky +// tests caused by the browser becoming inactive, we match on `::testing::_`. + +class BraveAdsTabHelperTest : public PlatformBrowserTest { public: void SetUpOnMainThread() override { - CertVerifierBrowserTest::SetUpOnMainThread(); - mock_cert_verifier()->set_default_result(net::OK); + PlatformBrowserTest::SetUpOnMainThread(); + + mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK); host_resolver()->AddRule("*", "127.0.0.1"); + InitEmbeddedTestServer(); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + PlatformBrowserTest::SetUpCommandLine(command_line); + + mock_cert_verifier_.SetUpCommandLine(command_line); + } + + void SetUpInProcessBrowserTestFixture() override { + PlatformBrowserTest::SetUpInProcessBrowserTestFixture(); + + mock_cert_verifier_.SetUpInProcessBrowserTestFixture(); + + callback_list_subscription_ = + BrowserContextDependencyManager::GetInstance() + ->RegisterCreateServicesCallbackForTesting(base::BindRepeating( + &BraveAdsTabHelperTest::OnWillCreateBrowserContextServices, + base::Unretained(this))); + } + + void TearDownInProcessBrowserTestFixture() override { + mock_cert_verifier_.TearDownInProcessBrowserTestFixture(); + + PlatformBrowserTest::TearDownInProcessBrowserTestFixture(); + } + + void OnWillCreateBrowserContextServices( + content::BrowserContext* const context) { + AdsServiceFactory::GetInstance()->SetTestingFactory( + context, base::BindRepeating(&BraveAdsTabHelperTest::CreateAdsService, + base::Unretained(this))); + } + + std::unique_ptr CreateAdsService( + content::BrowserContext* const /*context*/) { + // Since we are mocking the `AdsService`, a delegate is not required. Note + // that we are not testing the `AdsService` itself, these tests are focused + // on the `AdsTabHelper`. + auto ads_service = std::make_unique(/*delegate*/ nullptr); + ads_service_mock_ = ads_service.get(); + return ads_service; + } + + AdsServiceMock& ads_service_mock() { return *ads_service_mock_; } + + Profile* GetProfile() { return chrome_test_utils::GetProfile(this); } + + PrefService* GetPrefs() { return GetProfile()->GetPrefs(); } + + base::FilePath GetTestDataDir() { + const base::ScopedAllowBlockingForTesting scoped_allow_blocking; + return base::PathService::CheckedGet(brave::DIR_TEST_DATA); + } - const base::FilePath test_data_dir = - base::PathService::CheckedGet(brave::DIR_TEST_DATA); - https_server_.ServeFilesFromDirectory(test_data_dir); - https_server_.RegisterRequestHandler(base::BindRepeating( - &AdsTabHelperTest::HandleRequest, base::Unretained(this))); - ASSERT_TRUE(https_server_.Start()); + void InitEmbeddedTestServer() { + const base::FilePath test_data_dir = GetTestDataDir(); - GetActiveAdsTabHelper(browser())->SetAdsServiceForTesting(&ads_service()); + test_server_.ServeFilesFromDirectory(test_data_dir); + test_server_.RegisterRequestHandler(base::BindRepeating( + &BraveAdsTabHelperTest::HandleRequest, base::Unretained(this))); + test_server_handle_ = test_server_.StartAndReturnHandle(); + EXPECT_TRUE(test_server_handle_); } - PrefService* GetPrefs() { return browser()->profile()->GetPrefs(); } + int32_t TabId() { + content::WebContents* const web_contents = GetActiveWebContents(); + EXPECT_TRUE(web_contents); - net::EmbeddedTestServer& https_server() { return https_server_; } + return sessions::SessionTabHelper::IdForTab(web_contents).id(); + } + + content::WebContents* GetActiveWebContents() { + return chrome_test_utils::GetActiveWebContents(this); + } + + bool WaitForActiveWebContentsToLoad() { + content::WebContents* const web_contents = GetActiveWebContents(); + EXPECT_TRUE(web_contents); - AdsServiceMock& ads_service() { return ads_service_mock_; } + web_contents->GetController().LoadIfNecessary(); + + return content::WaitForLoadStop(web_contents); + } + + void CloseActiveWebContents() { + content::WebContents* const web_contents = GetActiveWebContents(); + chrome::CloseWebContents(browser(), web_contents, /*add_to_history=*/false); + } + + void NavigateToURL(const std::string_view relative_url, + const bool has_user_gesture) { + content::WebContents* const web_contents = GetActiveWebContents(); + EXPECT_TRUE(web_contents); + + const GURL url = test_server_.GetURL(kHostName, relative_url); + + content::NavigationController::LoadURLParams params(url); + if (has_user_gesture) { + return content::NavigateToURLBlockUntilNavigationsComplete( + web_contents, url, /*number_of_navigations=*/1, + /*ignore_uncommitted_navigations=*/true); + } + + EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(web_contents, url)); + } + + void SimulateHttpStatusCodePage(const int http_status_code) { + const std::string relative_url = + base::StringPrintf("%s?%s=%d", kHandleRequestUrlPath, + kHttpStatusCodeQueryKey, http_status_code); + NavigateToURL(relative_url, /*has_user_gesture=*/true); + } + + ::testing::AssertionResult ExecuteJavaScript(const std::string& javascript, + const bool has_user_gesture) { + content::WebContents* const web_contents = GetActiveWebContents(); + return content::ExecJs(web_contents, javascript, + has_user_gesture + ? content::EXECUTE_SCRIPT_DEFAULT_OPTIONS + : content::EXECUTE_SCRIPT_NO_USER_GESTURE); + } + + void GoBack() { + content::WebContents* const web_contents = GetActiveWebContents(); + EXPECT_TRUE(web_contents); + + content::NavigationController& navigation_controller = + web_contents->GetController(); + EXPECT_TRUE(navigation_controller.CanGoBack()); + navigation_controller.GoBack(); + } + + void GoForward() { + content::WebContents* const web_contents = GetActiveWebContents(); + EXPECT_TRUE(web_contents); + + content::NavigationController& navigation_controller = + web_contents->GetController(); + EXPECT_TRUE(navigation_controller.CanGoForward()); + navigation_controller.GoForward(); + } + + void Reload() { + content::WebContents* const web_contents = GetActiveWebContents(); + EXPECT_TRUE(web_contents); + + web_contents->GetController().Reload(content::ReloadType::NORMAL, + /*check_for_repost=*/false); + } + + void SimulateClick(const std::string& selectors, + const bool has_user_gesture) { + const std::string javascript = base::ReplaceStringPlaceholders( + R"(document.querySelector("$1").click();)", {selectors}, nullptr); + ExecuteJavaScript(javascript, has_user_gesture); + } + + void StartVideoPlayback(const std::string& selectors) { + const std::string javascript = base::ReplaceStringPlaceholders( + R"(document.querySelector("$1")?.play();)", {selectors}, nullptr); + + // Video elements must be executed with a user gesture. + ExecuteJavaScript(javascript, /*has_user_gesture=*/true); + } + + void PauseVideoPlayback(const std::string& selectors) { + const std::string javascript = base::ReplaceStringPlaceholders( + R"(document.querySelector("$1")?.pause();)", {selectors}, nullptr); + ExecuteJavaScript(javascript, /*has_user_gesture=*/true); + } + + void RestoreBrowser(Profile* const profile) { + CHECK(profile); + + SessionRestoreTestHelper session_restore_test_helper; + chrome::OpenWindowWithRestoredTabs(profile); + if (SessionRestore::IsRestoring(profile)) { + session_restore_test_helper.Wait(); + } + + SelectFirstBrowser(); + } + + std::unique_ptr HandleHttpStatusCodeQueryKey( + const std::string& value) const { + auto http_response = + std::make_unique(); + + int http_status_code_as_int; + EXPECT_TRUE(base::StringToInt(value, &http_status_code_as_int)); + const std::optional http_status_code = + net::TryToGetHttpStatusCode(http_status_code_as_int); + EXPECT_TRUE(http_status_code); + http_response->set_code(*http_status_code); + + http_response->set_content_type("text/html"); + const std::string http_status_code_page = base::StringPrintf( + R"( + + + + HTTP Status Code + + + + %d (%s) + + )", + *http_status_code, http_response->reason().c_str()); + http_response->set_content(http_status_code_page); + + return http_response; + } std::unique_ptr HandleRequest( - const net::test_server::HttpRequest& request) { - if (base::Contains(request.relative_url, k500ErrorPagePath)) { - // Return a 500 error without any content, causing the error page to be - // displayed. - auto response = std::make_unique(); - response->set_code(net::HTTP_INTERNAL_SERVER_ERROR); - return response; + const net::test_server::HttpRequest& http_request) const { + const GURL url = http_request.GetURL(); + if (url.path() != kHandleRequestUrlPath) { + // Do not handle the request. + return nullptr; } - if (base::Contains(request.relative_url, k404ErrorPagePath)) { - // Return a 404 error with HTML content. - auto response = std::make_unique(); - response->set_code(net::HTTP_NOT_FOUND); - response->set_content_type("text/html"); - response->set_content("Not Found"); - return response; + // Handle request. + base::StringPairs key_value_pairs; + base::SplitStringIntoKeyValuePairs(url.query(), '=', '&', &key_value_pairs); + + for (const auto& [key, value] : key_value_pairs) { + if (key == kHttpStatusCodeQueryKey) { + return HandleHttpStatusCodeQueryKey(value); + } } - return nullptr; + NOTREACHED_NORETURN() + << "Query key not found. Unable to handle the request."; + } + + std::vector RedirectChainExpectation( + const std::string_view relative_url) const { + const GURL url = test_server_.GetURL(kHostName, relative_url); + return {url}; } private: - net::EmbeddedTestServer https_server_{ + content::ContentMockCertVerifier mock_cert_verifier_; + + base::CallbackListSubscription callback_list_subscription_; + + raw_ptr ads_service_mock_ = nullptr; + + net::EmbeddedTestServer test_server_{ net::test_server::EmbeddedTestServer::TYPE_HTTPS}; - AdsServiceMock ads_service_mock_{nullptr}; + net::test_server::EmbeddedTestServerHandle test_server_handle_; }; -IN_PROC_BROWSER_TEST_F(AdsTabHelperTest, UserHasNotJoinedBraveRewards) { +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, NotifyTabDidChange) { + EXPECT_CALL( + ads_service_mock(), + NotifyTabDidChange(TabId(), + RedirectChainExpectation(kMultiPageApplicationWebpage), + /*is_new_navigation=*/true, /*is_restoring=*/false, + /*is_visible=*/::testing::_)) + .Times(::testing::AtLeast(1)); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + NotifyTabDidChangeIfTabWasRestored) { + EXPECT_CALL(ads_service_mock(), NotifyTabDidChange) + .Times(::testing::AnyNumber()); + + EXPECT_CALL( + ads_service_mock(), + NotifyTabDidChange(TabId(), + RedirectChainExpectation(kMultiPageApplicationWebpage), + /*is_new_navigation=*/true, /*is_restoring=*/false, + /*is_visible=*/::testing::_)) + .Times(::testing::AtLeast(1)); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); + + // Must occur before the browser is closed. + Profile* const profile = GetProfile(); + + const ScopedKeepAlive scoped_keep_alive(KeepAliveOrigin::SESSION_RESTORE, + KeepAliveRestartOption::DISABLED); + const ScopedProfileKeepAlive scoped_profile_keep_alive( + profile, ProfileKeepAliveOrigin::kSessionRestore); + CloseBrowserSynchronously(browser()); + + // We do not know the tab id until the tab is restored, so we match on + // `::testing::_`. + EXPECT_CALL(ads_service_mock(), + NotifyTabDidChange( + /*tab_id=*/::testing::_, + RedirectChainExpectation(kMultiPageApplicationWebpage), + /*is_new_navigation=*/false, /*is_restoring=*/true, + /*is_visible=*/::testing::_)); + RestoreBrowser(profile); + + EXPECT_TRUE(WaitForActiveWebContentsToLoad()); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, NotifyTabDidLoad) { + EXPECT_CALL(ads_service_mock(), NotifyTabDidLoad(TabId(), net::HTTP_OK)); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + NotifyTabDidLoadForHttpServerErrorResponsePage) { + EXPECT_CALL(ads_service_mock(), + NotifyTabDidLoad(TabId(), net::HTTP_INTERNAL_SERVER_ERROR)); + SimulateHttpStatusCodePage(net::HTTP_INTERNAL_SERVER_ERROR); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + NotifyTabDidLoadForHttpClientErrorResponsePage) { + EXPECT_CALL(ads_service_mock(), + NotifyTabDidLoad(TabId(), net::HTTP_NOT_FOUND)); + SimulateHttpStatusCodePage(net::HTTP_NOT_FOUND); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + NotifyTabDidLoadForHttpRedirectionResponsePage) { + EXPECT_CALL(ads_service_mock(), + NotifyTabDidLoad(TabId(), net::HTTP_MOVED_PERMANENTLY)); + SimulateHttpStatusCodePage(net::HTTP_MOVED_PERMANENTLY); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + NotifyTabDidLoadForHttpSuccessfulResponsePage) { + EXPECT_CALL(ads_service_mock(), NotifyTabDidLoad(TabId(), net::HTTP_OK)); + SimulateHttpStatusCodePage(net::HTTP_OK); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + NotifyTabHtmlContentDidChangeForRewardsUser) { + GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, true); + + base::RunLoop run_loop; + EXPECT_CALL( + ads_service_mock(), + NotifyTabHtmlContentDidChange( + TabId(), RedirectChainExpectation(kMultiPageApplicationWebpage), + kMultiPageApplicationWebpageHtmlContent)) + .WillOnce(base::test::RunOnceClosure(run_loop.QuitClosure())); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); + run_loop.Run(); +} + +IN_PROC_BROWSER_TEST_F( + BraveAdsTabHelperTest, + NotifyTabHtmlContentDidChangeWithEmptyHtmlForNonRewardsUser) { GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, false); - EXPECT_CALL(ads_service(), NotifyTabTextContentDidChange).Times(0); + base::RunLoop run_loop; + EXPECT_CALL( + ads_service_mock(), + NotifyTabHtmlContentDidChange( + TabId(), RedirectChainExpectation(kMultiPageApplicationWebpage), + /*html=*/::testing::IsEmpty())) + .WillOnce(base::test::RunOnceClosure(run_loop.QuitClosure())); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); + run_loop.Run(); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + DoNotNotifyTabHtmlContentDidChangeIfTabWasRestored) { + GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, true); + + base::RunLoop run_loop; + EXPECT_CALL(ads_service_mock(), NotifyTabHtmlContentDidChange) + .WillOnce(base::test::RunOnceClosure(run_loop.QuitClosure())); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); + run_loop.Run(); + ::testing::Mock::VerifyAndClearExpectations(&ads_service_mock()); + + // Must occur before the browser is closed. + Profile* const profile = GetProfile(); - base::RunLoop html_content_run_loop; - EXPECT_CALL(ads_service(), - NotifyTabHtmlContentDidChange(_, _, /*html=*/IsEmpty())) - .WillOnce(RunClosure(html_content_run_loop.QuitClosure())); + const ScopedKeepAlive scoped_keep_alive(KeepAliveOrigin::SESSION_RESTORE, + KeepAliveRestartOption::DISABLED); + const ScopedProfileKeepAlive scoped_profile_keep_alive( + profile, ProfileKeepAliveOrigin::kSessionRestore); + CloseBrowserSynchronously(browser()); - const GURL url = https_server().GetURL(kUrlDomain, kUrlPath); - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + // We should not notify about changes to the tab's HTML content, as the + // session will be restored and the tab will reload. + EXPECT_CALL(ads_service_mock(), NotifyTabHtmlContentDidChange).Times(0); + RestoreBrowser(profile); - html_content_run_loop.Run(); + EXPECT_TRUE(WaitForActiveWebContentsToLoad()); } -IN_PROC_BROWSER_TEST_F(AdsTabHelperTest, - UserHasJoinedBraveRewardsAndOptedInToNotificationAds) { +IN_PROC_BROWSER_TEST_F( + BraveAdsTabHelperTest, + DoNotNotifyTabHtmlContentDidChangeForPreviouslyCommittedNavigation) { + GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, true); + + base::RunLoop run_loop; + EXPECT_CALL(ads_service_mock(), NotifyTabHtmlContentDidChange) + .WillOnce(base::test::RunOnceClosure(run_loop.QuitClosure())); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); + run_loop.Run(); + ::testing::Mock::VerifyAndClearExpectations(&ads_service_mock()); + + EXPECT_CALL(ads_service_mock(), NotifyTabHtmlContentDidChange).Times(0); + GoBack(); + GoForward(); + Reload(); + + EXPECT_TRUE(WaitForActiveWebContentsToLoad()); +} + +IN_PROC_BROWSER_TEST_F( + BraveAdsTabHelperTest, + DoNotNotifyTabHtmlContentDidChangeForHttpClientErrorResponsePage) { + GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, true); + + EXPECT_CALL(ads_service_mock(), NotifyTabHtmlContentDidChange).Times(0); + SimulateHttpStatusCodePage(net::HTTP_NOT_FOUND); +} + +IN_PROC_BROWSER_TEST_F( + BraveAdsTabHelperTest, + DoNotNotifyTabHtmlContentDidChangeForHttpServerErrorResponsePage) { + GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, true); + + EXPECT_CALL(ads_service_mock(), NotifyTabHtmlContentDidChange).Times(0); + SimulateHttpStatusCodePage(net::HTTP_INTERNAL_SERVER_ERROR); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + NotifyTabHtmlContentDidChangeForSameDocumentNavigation) { + GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, true); + + { + base::RunLoop run_loop; + EXPECT_CALL(ads_service_mock(), NotifyTabHtmlContentDidChange) + .WillOnce(base::test::RunOnceClosure(run_loop.QuitClosure())); + NavigateToURL(kSinglePageApplicationWebpage, /*has_user_gesture=*/true); + run_loop.Run(); + ::testing::Mock::VerifyAndClearExpectations(&ads_service_mock()); + } + + { + base::RunLoop run_loop; + EXPECT_CALL(ads_service_mock(), + NotifyTabHtmlContentDidChange( + TabId(), ::testing::Contains(FileName("same_document")), + kSinglePageApplicationWebpageHtmlContent)) + .WillOnce(base::test::RunOnceClosure(run_loop.QuitClosure())); + SimulateClick(kSinglePageApplicationClickSelectors, + /*has_user_gesture=*/true); + run_loop.Run(); + } +} + +IN_PROC_BROWSER_TEST_F( + BraveAdsTabHelperTest, + NotifyTabTextContentDidChangeForRewardsUserOptedInToNotificationAds) { GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, true); GetPrefs()->SetBoolean(prefs::kOptedInToNotificationAds, true); - base::RunLoop text_content_run_loop; - EXPECT_CALL(ads_service(), - NotifyTabTextContentDidChange(_, _, /*text=*/Not(IsEmpty()))) - .WillOnce(RunClosure(text_content_run_loop.QuitClosure())); + base::RunLoop run_loop; + EXPECT_CALL( + ads_service_mock(), + NotifyTabTextContentDidChange( + TabId(), RedirectChainExpectation(kMultiPageApplicationWebpage), + kMultiPageApplicationWebpageTextContent)) + .WillOnce(base::test::RunOnceClosure(run_loop.QuitClosure())); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); + run_loop.Run(); +} - base::RunLoop html_content_run_loop; - EXPECT_CALL(ads_service(), - NotifyTabHtmlContentDidChange(_, _, /*html=*/Not(IsEmpty()))) - .WillOnce(RunClosure(html_content_run_loop.QuitClosure())); +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + DoNotNotifyTabTextContentDidChangeForNonRewardsUser) { + GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, false); - const GURL url = https_server().GetURL(kUrlDomain, kUrlPath); - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + EXPECT_CALL(ads_service_mock(), NotifyTabTextContentDidChange).Times(0); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); +} - text_content_run_loop.Run(); - html_content_run_loop.Run(); +IN_PROC_BROWSER_TEST_F( + BraveAdsTabHelperTest, + DoNotNotifyTabTextContentDidChangeForNonRewardsUserAndOptedOutOfNotificationAds) { + GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, false); + GetPrefs()->SetBoolean(prefs::kOptedInToNotificationAds, false); + + EXPECT_CALL(ads_service_mock(), NotifyTabTextContentDidChange).Times(0); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); } -IN_PROC_BROWSER_TEST_F(AdsTabHelperTest, - UserHasJoinedBraveRewardsAndOptedOutNotificationAds) { +IN_PROC_BROWSER_TEST_F( + BraveAdsTabHelperTest, + DoNotNotifyTabTextContentDidChangeForRewardsUserOptedOutOfNotificationAds) { GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, true); GetPrefs()->SetBoolean(prefs::kOptedInToNotificationAds, false); - EXPECT_CALL(ads_service(), NotifyTabTextContentDidChange).Times(0); + EXPECT_CALL(ads_service_mock(), NotifyTabTextContentDidChange).Times(0); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + DoNotNotifyTabTextContentDidChangeIfTabWasRestored) { + GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, true); + GetPrefs()->SetBoolean(prefs::kOptedInToNotificationAds, true); + + base::RunLoop run_loop; + EXPECT_CALL(ads_service_mock(), NotifyTabTextContentDidChange) + .WillOnce(base::test::RunOnceClosure(run_loop.QuitClosure())); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); + run_loop.Run(); + ::testing::Mock::VerifyAndClearExpectations(&ads_service_mock()); + + // Must occur before the browser is closed. + Profile* const profile = GetProfile(); + + const ScopedKeepAlive scoped_keep_alive(KeepAliveOrigin::SESSION_RESTORE, + KeepAliveRestartOption::DISABLED); + const ScopedProfileKeepAlive scoped_profile_keep_alive( + profile, ProfileKeepAliveOrigin::kSessionRestore); + CloseBrowserSynchronously(browser()); + + // We should not notify about changes to the tab's text content, as the + // session will be restored and the tab will reload. + EXPECT_CALL(ads_service_mock(), NotifyTabTextContentDidChange).Times(0); + RestoreBrowser(profile); + + EXPECT_TRUE(WaitForActiveWebContentsToLoad()); +} + +IN_PROC_BROWSER_TEST_F( + BraveAdsTabHelperTest, + DoNotNotifyTabTextContentDidChangeForPreviouslyCommittedNavigation) { + GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, true); + GetPrefs()->SetBoolean(prefs::kOptedInToNotificationAds, true); - base::RunLoop html_content_run_loop; - EXPECT_CALL(ads_service(), - NotifyTabHtmlContentDidChange(_, _, /*html=*/Not(IsEmpty()))) - .WillOnce(RunClosure(html_content_run_loop.QuitClosure())); + base::RunLoop run_loop; + EXPECT_CALL(ads_service_mock(), NotifyTabTextContentDidChange) + .WillOnce(base::test::RunOnceClosure(run_loop.QuitClosure())); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); + run_loop.Run(); + ::testing::Mock::VerifyAndClearExpectations(&ads_service_mock()); - const GURL url = https_server().GetURL(kUrlDomain, kUrlPath); - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + EXPECT_CALL(ads_service_mock(), NotifyTabTextContentDidChange).Times(0); + GoBack(); + GoForward(); + Reload(); - html_content_run_loop.Run(); + EXPECT_TRUE(WaitForActiveWebContentsToLoad()); } -IN_PROC_BROWSER_TEST_F(AdsTabHelperTest, LoadSinglePageApplication) { +IN_PROC_BROWSER_TEST_F( + BraveAdsTabHelperTest, + DoNotNotifyTabTextContentDidChangeForHttpClientErrorResponsePage) { GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, true); GetPrefs()->SetBoolean(prefs::kOptedInToNotificationAds, true); - base::RunLoop text_content_run_loop; - EXPECT_CALL(ads_service(), - NotifyTabTextContentDidChange(_, _, /*text=*/Not(IsEmpty()))) - .WillOnce(RunClosure(text_content_run_loop.QuitClosure())); + EXPECT_CALL(ads_service_mock(), NotifyTabTextContentDidChange).Times(0); + SimulateHttpStatusCodePage(net::HTTP_NOT_FOUND); +} - base::RunLoop html_content_run_loop; - EXPECT_CALL(ads_service(), - NotifyTabHtmlContentDidChange(_, _, /*html=*/Not(IsEmpty()))) - .WillOnce(RunClosure(html_content_run_loop.QuitClosure())); +IN_PROC_BROWSER_TEST_F( + BraveAdsTabHelperTest, + DoNotNotifyTabTextContentDidChangeForHttpServerErrorResponsePage) { + GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, true); + GetPrefs()->SetBoolean(prefs::kOptedInToNotificationAds, true); - const GURL url = - https_server().GetURL(kUrlDomain, kSinglePageApplicationUrlPath); - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + EXPECT_CALL(ads_service_mock(), NotifyTabTextContentDidChange).Times(0); + SimulateHttpStatusCodePage(net::HTTP_INTERNAL_SERVER_ERROR); +} - text_content_run_loop.Run(); - html_content_run_loop.Run(); +IN_PROC_BROWSER_TEST_F( + BraveAdsTabHelperTest, + DoNotNotifyTabTextContentDidChangeForSameDocumentNavigation) { + GetPrefs()->SetBoolean(brave_rewards::prefs::kEnabled, true); + GetPrefs()->SetBoolean(prefs::kOptedInToNotificationAds, true); + + base::RunLoop run_loop; + EXPECT_CALL(ads_service_mock(), NotifyTabTextContentDidChange) + .WillOnce(base::test::RunOnceClosure(run_loop.QuitClosure())); + NavigateToURL(kSinglePageApplicationWebpage, /*has_user_gesture=*/true); + run_loop.Run(); + ::testing::Mock::VerifyAndClearExpectations(&ads_service_mock()); + + EXPECT_CALL(ads_service_mock(), NotifyTabTextContentDidChange).Times(0); + SimulateClick(kSinglePageApplicationClickSelectors, + /*has_user_gesture=*/true); + + EXPECT_TRUE(WaitForActiveWebContentsToLoad()); } -IN_PROC_BROWSER_TEST_F(AdsTabHelperTest, NotifyTabDidChange) { - base::RunLoop tab_did_change_run_loop; - EXPECT_CALL( - ads_service(), - NotifyTabDidChange(/*tab_id=*/_, /*redirect_chain=*/_, - /*is_new_navigation=*/true, /*is_restoring=*/false, - /*is_error_page_=*/false, /*is_visible=*/_)) - .WillRepeatedly(RunClosure(tab_did_change_run_loop.QuitClosure())); +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + NotifyTabDidStartPlayingMediaForAutoplayVideo) { + GetPrefs()->SetBoolean(::prefs::kAutoplayAllowed, true); + + content::WebContents* const web_contents = GetActiveWebContents(); + MediaWaiter waiter(web_contents); - const GURL url = https_server().GetURL(kUrlDomain, kUrlPath); - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + EXPECT_CALL(ads_service_mock(), NotifyTabDidStartPlayingMedia); + NavigateToURL(kAutoplayVideoWebpage, /*has_user_gesture=*/true); - tab_did_change_run_loop.Run(); + waiter.WaitForMediaStartedPlaying(); } -IN_PROC_BROWSER_TEST_F(AdsTabHelperTest, - NotifyTabDidChangeForServerErrorResponsePage) { - // Mock unexpected NotifyTabDidChange calls to NotifyTabDidChange on browser - // test startup. - EXPECT_CALL(ads_service(), - NotifyTabDidChange(/*tab_id=*/_, /*redirect_chain=*/_, - /*is_new_navigation=*/_, /*is_restoring=*/_, - /*is_error_page_=*/_, /*is_visible=*/_)) - .Times(testing::AnyNumber()); +IN_PROC_BROWSER_TEST_F( + BraveAdsTabHelperTest, + DoNotNotifyTabDidStartPlayingMediaForAutoplayVideoIfDisallowed) { + GetPrefs()->SetBoolean(::prefs::kAutoplayAllowed, false); - base::RunLoop tab_did_change_run_loop; - EXPECT_CALL( - ads_service(), - NotifyTabDidChange(/*tab_id=*/_, /*redirect_chain=*/_, - /*is_new_navigation=*/true, /*is_restoring=*/false, - /*is_error_page_=*/true, /*is_visible=*/_)) - .WillRepeatedly(RunClosure(tab_did_change_run_loop.QuitClosure())); + content::WebContents* const web_contents = GetActiveWebContents(); + MediaWaiter waiter(web_contents); - const GURL url = https_server().GetURL(kUrlDomain, k500ErrorPagePath); - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + EXPECT_CALL(ads_service_mock(), NotifyTabDidStartPlayingMedia).Times(0); + NavigateToURL(kAutoplayVideoWebpage, /*has_user_gesture=*/true); - tab_did_change_run_loop.Run(); + waiter.WaitForMediaSessionCreated(); } -IN_PROC_BROWSER_TEST_F(AdsTabHelperTest, - NotifyTabDidChangeForClientErrorResponsePage) { - // Mock unexpected NotifyTabDidChange calls to NotifyTabDidChange on browser - // test startup. - EXPECT_CALL(ads_service(), - NotifyTabDidChange(/*tab_id=*/_, /*redirect_chain=*/_, - /*is_new_navigation=*/_, /*is_restoring=*/_, - /*is_error_page_=*/_, /*is_visible=*/_)) - .Times(testing::AnyNumber()); +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + NotifyTabDidStopPlayingMediaForAutoplayVideo) { + GetPrefs()->SetBoolean(::prefs::kAutoplayAllowed, true); - base::RunLoop tab_did_change_run_loop; - EXPECT_CALL( - ads_service(), - NotifyTabDidChange(/*tab_id=*/_, /*redirect_chain=*/_, - /*is_new_navigation=*/true, /*is_restoring=*/false, - /*is_error_page_=*/true, /*is_visible=*/_)) - .WillRepeatedly(RunClosure(tab_did_change_run_loop.QuitClosure())); + content::WebContents* const web_contents = GetActiveWebContents(); + MediaWaiter waiter(web_contents); + + EXPECT_CALL(ads_service_mock(), NotifyTabDidStartPlayingMedia); + NavigateToURL(kAutoplayVideoWebpage, /*has_user_gesture=*/true); - const GURL url = https_server().GetURL(kUrlDomain, k404ErrorPagePath); - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + waiter.WaitForMediaStartedPlaying(); - tab_did_change_run_loop.Run(); + EXPECT_CALL(ads_service_mock(), NotifyTabDidStopPlayingMedia); + PauseVideoPlayback(kVideoJavascriptDocumentQuerySelectors); } -IN_PROC_BROWSER_TEST_F(AdsTabHelperTest, IncognitoBrowser) { - const GURL url = https_server().GetURL(kUrlDomain, kUrlPath); - Browser* incognito_browser = OpenURLOffTheRecord(browser()->profile(), url); - AdsTabHelper* incognito_ads_tab_helper = - GetActiveAdsTabHelper(incognito_browser); - EXPECT_FALSE(incognito_ads_tab_helper->ads_service()); +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, NotifyTabDidStartPlayingMedia) { + NavigateToURL(kVideoWebpage, /*has_user_gesture=*/true); + + EXPECT_CALL(ads_service_mock(), NotifyTabDidStartPlayingMedia); + StartVideoPlayback(kVideoJavascriptDocumentQuerySelectors); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, NotifyTabDidStopPlayingMedia) { + NavigateToURL(kVideoWebpage, /*has_user_gesture=*/true); + + StartVideoPlayback(kVideoJavascriptDocumentQuerySelectors); + + EXPECT_CALL(ads_service_mock(), NotifyTabDidStopPlayingMedia); + PauseVideoPlayback(kVideoJavascriptDocumentQuerySelectors); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, NotifyDidCloseTab) { + EXPECT_CALL(ads_service_mock(), NotifyDidCloseTab); + CloseActiveWebContents(); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, NotifyUserGestureEventTriggered) { + EXPECT_CALL(ads_service_mock(), NotifyUserGestureEventTriggered) + .Times(::testing::AtLeast(1)); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + DoNotNotifyUserGestureEventTriggered) { + EXPECT_CALL(ads_service_mock(), NotifyUserGestureEventTriggered).Times(0); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/false); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + DoNotNotifyUserGestureEventTriggeredIfTabWasRestored) { + EXPECT_CALL(ads_service_mock(), NotifyUserGestureEventTriggered) + .Times(::testing::AtLeast(1)); + NavigateToURL(kMultiPageApplicationWebpage, /*has_user_gesture=*/true); + ::testing::Mock::VerifyAndClearExpectations(&ads_service_mock()); + + // Must occur before the browser is closed. + Profile* const profile = GetProfile(); + + const ScopedKeepAlive scoped_keep_alive(KeepAliveOrigin::SESSION_RESTORE, + KeepAliveRestartOption::DISABLED); + const ScopedProfileKeepAlive scoped_profile_keep_alive( + profile, ProfileKeepAliveOrigin::kSessionRestore); + CloseBrowserSynchronously(browser()); + + EXPECT_CALL(ads_service_mock(), NotifyUserGestureEventTriggered).Times(0); + RestoreBrowser(profile); + + EXPECT_TRUE(WaitForActiveWebContentsToLoad()); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + CreativeAdsServiceForRegularBrowser) { + content::WebContents* const web_contents = GetActiveWebContents(); + ASSERT_TRUE(web_contents); + + AdsTabHelper* const ads_tab_helper = + AdsTabHelper::FromWebContents(web_contents); + ASSERT_TRUE(ads_tab_helper); + + EXPECT_TRUE(ads_tab_helper->ads_service()); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + DoNotCreativeAdsServiceForIncognitoBrowser) { + const Browser* const browser = CreateIncognitoBrowser(); + + content::WebContents* const web_contents = + browser->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(web_contents); + + AdsTabHelper* const ads_tab_helper = + AdsTabHelper::FromWebContents(web_contents); + ASSERT_TRUE(ads_tab_helper); + + EXPECT_FALSE(ads_tab_helper->ads_service()); +} + +IN_PROC_BROWSER_TEST_F(BraveAdsTabHelperTest, + DoNotCreativeAdsServiceForGuestBrowser) { + const Browser* const browser = CreateGuestBrowser(); + + content::WebContents* const web_contents = + browser->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(web_contents); + + AdsTabHelper* const ads_tab_helper = + AdsTabHelper::FromWebContents(web_contents); + ASSERT_TRUE(ads_tab_helper); + + EXPECT_FALSE(ads_tab_helper->ads_service()); } } // namespace brave_ads diff --git a/test/BUILD.gn b/test/BUILD.gn index 2e1726abcb48..c3ea3f2e27db 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -838,6 +838,7 @@ test("brave_browser_tests") { "//brave/browser/autoplay:browser_tests", "//brave/browser/brave_ads", "//brave/browser/brave_ads:browser_tests", + "//brave/browser/brave_ads/tabs:browser_tests", "//brave/browser/brave_news:browser_tests", "//brave/browser/brave_rewards", "//brave/browser/brave_rewards/test:browser_tests", diff --git a/test/data/brave_ads/autoplay_video.html b/test/data/brave_ads/autoplay_video.html new file mode 100644 index 000000000000..12429ed65fa4 --- /dev/null +++ b/test/data/brave_ads/autoplay_video.html @@ -0,0 +1,33 @@ + + + + + Brave stops ads from following you + + + + + +

Yeah, Brave blocks that

+ + + + + diff --git a/test/data/brave_ads/basic_page.html b/test/data/brave_ads/basic_page.html deleted file mode 100644 index a98f23c54734..000000000000 --- a/test/data/brave_ads/basic_page.html +++ /dev/null @@ -1,9 +0,0 @@ - -Basic Page - -

Page header

-

- Page content -

- - diff --git a/test/data/brave_ads/multi_page_application.html b/test/data/brave_ads/multi_page_application.html new file mode 100644 index 000000000000..6bcf38faead6 --- /dev/null +++ b/test/data/brave_ads/multi_page_application.html @@ -0,0 +1,42 @@ + + + + + Adventure Awaits + + + +

Welcome to Your Adventure

+

+ Embark on a journey of learning and discovery. Each step you take brings you closer to mastering new skills and + achieving your goals. +

+ +
+ "The only limit to our realization of tomorrow is our doubts of today." - Franklin D. Roosevelt +
+ + + + + + + + + + + + + + + + + +
TaskStatus
Learn RustCompleted
Contribute to a GitHub repositoryIn Progress
Build a mobile appPending
+ + + diff --git a/test/data/brave_ads/single_page_application.html b/test/data/brave_ads/single_page_application.html index 3bce6f88bfd0..8fe0b73894e6 100644 --- a/test/data/brave_ads/single_page_application.html +++ b/test/data/brave_ads/single_page_application.html @@ -1,48 +1,56 @@ - + + + Single Page Application - -

Header

-
  • Home
  • -
  • Eagle
  • -
  • Vulture
  • + +

    Home

    + + diff --git a/test/data/brave_ads/video.html b/test/data/brave_ads/video.html new file mode 100644 index 000000000000..d99be8d8a8e8 --- /dev/null +++ b/test/data/brave_ads/video.html @@ -0,0 +1,33 @@ + + + + + Brave stops ads from following you + + + + + +

    Yeah, Brave blocks that

    + + + + + diff --git a/test/data/brave_ads/video.mp4 b/test/data/brave_ads/video.mp4 new file mode 100644 index 000000000000..69889b2bf485 Binary files /dev/null and b/test/data/brave_ads/video.mp4 differ