Commit 296c30f2 authored by Jazz Xu's avatar Jazz Xu Committed by Commit Bot

GMC: Add interactive tests for Zenith PiP button.

Bug: 1060291
Change-Id: I6c70eb25b9b8e3c9f675b0030a42fe712a89715d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2129018Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarTommy Steimel <steimel@chromium.org>
Commit-Queue: Jazz Xu <jazzhsu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#757950}
parent 12e389c7
...@@ -16,6 +16,9 @@ class MediaNotificationContainerObserver : public base::CheckedObserver { ...@@ -16,6 +16,9 @@ class MediaNotificationContainerObserver : public base::CheckedObserver {
// Called when the metadata displayed in the container changes. // Called when the metadata displayed in the container changes.
virtual void OnContainerMetadataChanged() = 0; virtual void OnContainerMetadataChanged() = 0;
// Called when the action buttons in the container change.
virtual void OnContainerActionsChanged() = 0;
// Called when the container is clicked. // Called when the container is clicked.
virtual void OnContainerClicked(const std::string& id) = 0; virtual void OnContainerClicked(const std::string& id) = 0;
......
...@@ -71,6 +71,7 @@ class MediaNotificationService ...@@ -71,6 +71,7 @@ class MediaNotificationService
// MediaNotificationContainerObserver implementation. // MediaNotificationContainerObserver implementation.
void OnContainerExpanded(bool expanded) override {} void OnContainerExpanded(bool expanded) override {}
void OnContainerMetadataChanged() override {} void OnContainerMetadataChanged() override {}
void OnContainerActionsChanged() override {}
void OnContainerClicked(const std::string& id) override; void OnContainerClicked(const std::string& id) override;
void OnContainerDismissed(const std::string& id) override; void OnContainerDismissed(const std::string& id) override;
void OnContainerDestroyed(const std::string& id) override; void OnContainerDestroyed(const std::string& id) override;
......
...@@ -131,6 +131,11 @@ void MediaDialogView::OnContainerMetadataChanged() { ...@@ -131,6 +131,11 @@ void MediaDialogView::OnContainerMetadataChanged() {
observer.OnMediaSessionMetadataUpdated(); observer.OnMediaSessionMetadataUpdated();
} }
void MediaDialogView::OnContainerActionsChanged() {
for (auto& observer : observers_)
observer.OnMediaSessionActionsChanged();
}
void MediaDialogView::OnContainerDestroyed(const std::string& id) { void MediaDialogView::OnContainerDestroyed(const std::string& id) {
auto iter = observed_containers_.find(id); auto iter = observed_containers_.find(id);
DCHECK(iter != observed_containers_.end()); DCHECK(iter != observed_containers_.end());
......
...@@ -43,6 +43,7 @@ class MediaDialogView : public views::BubbleDialogDelegateView, ...@@ -43,6 +43,7 @@ class MediaDialogView : public views::BubbleDialogDelegateView,
// MediaNotificationContainerObserver implementation. // MediaNotificationContainerObserver implementation.
void OnContainerExpanded(bool expanded) override; void OnContainerExpanded(bool expanded) override;
void OnContainerMetadataChanged() override; void OnContainerMetadataChanged() override;
void OnContainerActionsChanged() override;
void OnContainerClicked(const std::string& id) override {} void OnContainerClicked(const std::string& id) override {}
void OnContainerDismissed(const std::string& id) override {} void OnContainerDismissed(const std::string& id) override {}
void OnContainerDestroyed(const std::string& id) override; void OnContainerDestroyed(const std::string& id) override;
......
...@@ -55,6 +55,10 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver, ...@@ -55,6 +55,10 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver,
void OnMediaSessionMetadataUpdated() override { CheckDialogForText(); } void OnMediaSessionMetadataUpdated() override { CheckDialogForText(); }
void OnMediaSessionActionsChanged() override {
CheckPictureInPictureButton();
}
// MediaToolbarButtonObserver implementation. // MediaToolbarButtonObserver implementation.
void OnMediaDialogOpened() override { void OnMediaDialogOpened() override {
waiting_for_dialog_opened_ = false; waiting_for_dialog_opened_ = false;
...@@ -106,6 +110,17 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver, ...@@ -106,6 +110,17 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver,
Wait(); Wait();
} }
void WaitForPictureInPictureButtonVisibility(bool visible) {
if (CheckPictureInPictureButtonVisibility(visible))
return;
waiting_for_pip_visibility_changed_ = true;
expected_pip_visibility_ = visible;
observed_dialog_ = MediaDialogView::GetDialogViewForTesting();
observed_dialog_->AddObserver(this);
Wait();
}
private: private:
void CheckDialogForText() { void CheckDialogForText() {
if (!waiting_for_dialog_to_contain_text_) if (!waiting_for_dialog_to_contain_text_)
...@@ -129,13 +144,25 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver, ...@@ -129,13 +144,25 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver,
MaybeStopWaiting(); MaybeStopWaiting();
} }
void CheckPictureInPictureButton() {
if (!waiting_for_pip_visibility_changed_)
return;
if (!CheckPictureInPictureButtonVisibility(expected_pip_visibility_))
return;
waiting_for_pip_visibility_changed_ = false;
MaybeStopWaiting();
}
void MaybeStopWaiting() { void MaybeStopWaiting() {
if (!run_loop_) if (!run_loop_)
return; return;
if (!waiting_for_dialog_opened_ && !waiting_for_button_shown_ && if (!waiting_for_dialog_opened_ && !waiting_for_button_shown_ &&
!waiting_for_dialog_to_contain_text_ && !waiting_for_dialog_to_contain_text_ &&
!waiting_for_notification_count_) { !waiting_for_notification_count_ &&
!waiting_for_pip_visibility_changed_) {
run_loop_->Quit(); run_loop_->Quit();
} }
} }
...@@ -165,6 +192,17 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver, ...@@ -165,6 +192,17 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver,
return false; return false;
} }
bool CheckPictureInPictureButtonVisibility(bool visible) {
const auto notification_pair = MediaDialogView::GetDialogViewForTesting()
->GetNotificationsForTesting()
.begin();
const media_message_center::MediaNotificationViewImpl* view =
notification_pair->second->view_for_testing();
return view->picture_in_picture_button_for_testing()->GetVisible() ==
visible;
}
int GetNotificationCount() { int GetNotificationCount() {
return MediaDialogView::GetDialogViewForTesting() return MediaDialogView::GetDialogViewForTesting()
->GetNotificationsForTesting() ->GetNotificationsForTesting()
...@@ -177,11 +215,13 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver, ...@@ -177,11 +215,13 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver,
bool waiting_for_dialog_opened_ = false; bool waiting_for_dialog_opened_ = false;
bool waiting_for_button_shown_ = false; bool waiting_for_button_shown_ = false;
bool waiting_for_notification_count_ = false; bool waiting_for_notification_count_ = false;
bool waiting_for_pip_visibility_changed_ = false;
MediaDialogView* observed_dialog_ = nullptr; MediaDialogView* observed_dialog_ = nullptr;
bool waiting_for_dialog_to_contain_text_ = false; bool waiting_for_dialog_to_contain_text_ = false;
base::string16 expected_text_; base::string16 expected_text_;
int expected_notification_count_ = 0; int expected_notification_count_ = 0;
bool expected_pip_visibility_ = false;
DISALLOW_COPY_AND_ASSIGN(MediaToolbarButtonWatcher); DISALLOW_COPY_AND_ASSIGN(MediaToolbarButtonWatcher);
}; };
...@@ -345,6 +385,30 @@ class MediaDialogViewBrowserTest : public InProcessBrowserTest { ...@@ -345,6 +385,30 @@ class MediaDialogViewBrowserTest : public InProcessBrowserTest {
observer.Wait(); observer.Wait();
} }
void DisablePictureInPicture() {
GetActiveWebContents()->GetMainFrame()->ExecuteJavaScriptForTests(
base::ASCIIToUTF16("disablePictureInPicture()"), base::NullCallback());
}
void EnablePictureInPicture() {
GetActiveWebContents()->GetMainFrame()->ExecuteJavaScriptForTests(
base::ASCIIToUTF16("enablePictureInPicture()"), base::NullCallback());
}
void WaitForEnterPictureInPicture() {
content::MediaStartStopObserver observer(
GetActiveWebContents(),
content::MediaStartStopObserver::Type::kEnterPictureInPicture);
observer.Wait();
}
void WaitForExitPictureInPicture() {
content::MediaStartStopObserver observer(
GetActiveWebContents(),
content::MediaStartStopObserver::Type::kExitPictureInPicture);
observer.Wait();
}
void WaitForDialogOpened() { void WaitForDialogOpened() {
MediaToolbarButtonWatcher(GetToolbarIcon()).WaitForDialogOpened(); MediaToolbarButtonWatcher(GetToolbarIcon()).WaitForDialogOpened();
} }
...@@ -360,6 +424,11 @@ class MediaDialogViewBrowserTest : public InProcessBrowserTest { ...@@ -360,6 +424,11 @@ class MediaDialogViewBrowserTest : public InProcessBrowserTest {
MediaToolbarButtonWatcher(GetToolbarIcon()).WaitForNotificationCount(count); MediaToolbarButtonWatcher(GetToolbarIcon()).WaitForNotificationCount(count);
} }
void WaitForPictureInPictureButtonVisibility(bool visible) {
MediaToolbarButtonWatcher(GetToolbarIcon())
.WaitForPictureInPictureButtonVisibility(visible);
}
void ClickPauseButtonOnDialog() { void ClickPauseButtonOnDialog() {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
ASSERT_TRUE(MediaDialogView::IsShowing()); ASSERT_TRUE(MediaDialogView::IsShowing());
...@@ -372,6 +441,18 @@ class MediaDialogViewBrowserTest : public InProcessBrowserTest { ...@@ -372,6 +441,18 @@ class MediaDialogViewBrowserTest : public InProcessBrowserTest {
ClickButton(GetButtonForAction(MediaSessionAction::kPlay)); ClickButton(GetButtonForAction(MediaSessionAction::kPlay));
} }
void ClickEnterPictureInPictureButtonOnDialog() {
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(MediaDialogView::IsShowing());
ClickButton(GetButtonForAction(MediaSessionAction::kEnterPictureInPicture));
}
void ClickExitPictureInPictureButtonOnDialog() {
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(MediaDialogView::IsShowing());
ClickButton(GetButtonForAction(MediaSessionAction::kExitPictureInPicture));
}
void ClickNotificationByTitle(const base::string16& title) { void ClickNotificationByTitle(const base::string16& title) {
ASSERT_TRUE(MediaDialogView::IsShowing()); ASSERT_TRUE(MediaDialogView::IsShowing());
MediaNotificationContainerImplView* notification = MediaNotificationContainerImplView* notification =
...@@ -570,3 +651,42 @@ IN_PROC_BROWSER_TEST_F(MediaDialogViewBrowserTest, ShowsCastSession) { ...@@ -570,3 +651,42 @@ IN_PROC_BROWSER_TEST_F(MediaDialogViewBrowserTest, ShowsCastSession) {
base::UTF8ToUTF16(route_description + " \xC2\xB7 " + sink_name)); base::UTF8ToUTF16(route_description + " \xC2\xB7 " + sink_name));
WaitForNotificationCount(1); WaitForNotificationCount(1);
} }
IN_PROC_BROWSER_TEST_F(MediaDialogViewBrowserTest, PictureInPicture) {
// Open a tab and play media.
OpenTestURL();
StartPlayback();
WaitForStart();
// Open the media dialog.
WaitForVisibleToolbarIcon();
ClickToolbarIcon();
WaitForDialogOpened();
EXPECT_TRUE(IsDialogVisible());
ClickEnterPictureInPictureButtonOnDialog();
WaitForEnterPictureInPicture();
ClickExitPictureInPictureButtonOnDialog();
WaitForExitPictureInPicture();
}
IN_PROC_BROWSER_TEST_F(MediaDialogViewBrowserTest,
PictureInPictureButtonVisibility) {
// Open a tab and play media.
OpenTestURL();
StartPlayback();
WaitForStart();
// Open the media dialog.
WaitForVisibleToolbarIcon();
ClickToolbarIcon();
WaitForDialogOpened();
EXPECT_TRUE(IsDialogVisible());
DisablePictureInPicture();
WaitForPictureInPictureButtonVisibility(false);
EnablePictureInPicture();
WaitForPictureInPictureButtonVisibility(true);
}
...@@ -18,6 +18,9 @@ class MediaDialogViewObserver : public base::CheckedObserver { ...@@ -18,6 +18,9 @@ class MediaDialogViewObserver : public base::CheckedObserver {
// Called when a shown media session's metadata is updated. // Called when a shown media session's metadata is updated.
virtual void OnMediaSessionMetadataUpdated() = 0; virtual void OnMediaSessionMetadataUpdated() = 0;
// Called when a shown media session's actions are changed.
virtual void OnMediaSessionActionsChanged() = 0;
protected: protected:
~MediaDialogViewObserver() override = default; ~MediaDialogViewObserver() override = default;
}; };
......
...@@ -226,6 +226,9 @@ void MediaNotificationContainerImplView::OnVisibleActionsChanged( ...@@ -226,6 +226,9 @@ void MediaNotificationContainerImplView::OnVisibleActionsChanged(
actions, actions,
media_session::mojom::MediaSessionAction::kExitPictureInPicture)); media_session::mojom::MediaSessionAction::kExitPictureInPicture));
ForceExpandedState(); ForceExpandedState();
for (auto& observer : observers_)
observer.OnContainerActionsChanged();
} }
void MediaNotificationContainerImplView::OnMediaArtworkChanged( void MediaNotificationContainerImplView::OnMediaArtworkChanged(
......
...@@ -38,6 +38,7 @@ class MockMediaNotificationContainerObserver ...@@ -38,6 +38,7 @@ class MockMediaNotificationContainerObserver
// MediaNotificationContainerObserver implementation. // MediaNotificationContainerObserver implementation.
MOCK_METHOD1(OnContainerExpanded, void(bool expanded)); MOCK_METHOD1(OnContainerExpanded, void(bool expanded));
MOCK_METHOD0(OnContainerMetadataChanged, void()); MOCK_METHOD0(OnContainerMetadataChanged, void());
MOCK_METHOD0(OnContainerActionsChanged, void());
MOCK_METHOD1(OnContainerClicked, void(const std::string& id)); MOCK_METHOD1(OnContainerClicked, void(const std::string& id));
MOCK_METHOD1(OnContainerDismissed, void(const std::string& id)); MOCK_METHOD1(OnContainerDismissed, void(const std::string& id));
MOCK_METHOD1(OnContainerDestroyed, void(const std::string& id)); MOCK_METHOD1(OnContainerDestroyed, void(const std::string& id));
......
...@@ -39,6 +39,14 @@ function setupActionHandlers() { ...@@ -39,6 +39,14 @@ function setupActionHandlers() {
navigator.mediaSession.setActionHandler('play', _ => { video.play(); }); navigator.mediaSession.setActionHandler('play', _ => { video.play(); });
navigator.mediaSession.setActionHandler('pause', _ => { video.pause(); }); navigator.mediaSession.setActionHandler('pause', _ => { video.pause(); });
} }
function disablePictureInPicture() {
video.disablePictureInPicture = true;
}
function enablePictureInPicture() {
video.disablePictureInPicture = false;
}
</script> </script>
</body> </body>
</html> </html>
...@@ -86,6 +86,10 @@ class COMPONENT_EXPORT(MEDIA_MESSAGE_CENTER) MediaNotificationViewImpl ...@@ -86,6 +86,10 @@ class COMPONENT_EXPORT(MEDIA_MESSAGE_CENTER) MediaNotificationViewImpl
const views::Label* artist_label_for_testing() const { return artist_label_; } const views::Label* artist_label_for_testing() const { return artist_label_; }
const views::Button* picture_in_picture_button_for_testing() const {
return picture_in_picture_button_;
}
views::Button* GetHeaderRowForTesting() const; views::Button* GetHeaderRowForTesting() const;
base::string16 GetSourceTitleForTesting() const; base::string16 GetSourceTitleForTesting() const;
......
...@@ -20,6 +20,17 @@ void MediaStartStopObserver::MediaStartedPlaying(const MediaPlayerInfo& info, ...@@ -20,6 +20,17 @@ void MediaStartStopObserver::MediaStartedPlaying(const MediaPlayerInfo& info,
run_loop_.Quit(); run_loop_.Quit();
} }
void MediaStartStopObserver::MediaPictureInPictureChanged(
bool is_picture_in_picture) {
if (is_picture_in_picture && type_ != Type::kEnterPictureInPicture)
return;
if (!is_picture_in_picture && type_ != Type::kExitPictureInPicture)
return;
run_loop_.Quit();
}
void MediaStartStopObserver::MediaStoppedPlaying( void MediaStartStopObserver::MediaStoppedPlaying(
const MediaPlayerInfo& info, const MediaPlayerInfo& info,
const MediaPlayerId& id, const MediaPlayerId& id,
......
...@@ -16,7 +16,12 @@ class WebContents; ...@@ -16,7 +16,12 @@ class WebContents;
// Used in tests to wait for media in a WebContents to start or stop playing. // Used in tests to wait for media in a WebContents to start or stop playing.
class MediaStartStopObserver : public WebContentsObserver { class MediaStartStopObserver : public WebContentsObserver {
public: public:
enum class Type { kStart, kStop }; enum class Type {
kStart,
kStop,
kEnterPictureInPicture,
kExitPictureInPicture
};
MediaStartStopObserver(WebContents* web_contents, Type type); MediaStartStopObserver(WebContents* web_contents, Type type);
~MediaStartStopObserver() override; ~MediaStartStopObserver() override;
...@@ -29,6 +34,8 @@ class MediaStartStopObserver : public WebContentsObserver { ...@@ -29,6 +34,8 @@ class MediaStartStopObserver : public WebContentsObserver {
const MediaPlayerId& id, const MediaPlayerId& id,
WebContentsObserver::MediaStoppedReason reason) override; WebContentsObserver::MediaStoppedReason reason) override;
void MediaPictureInPictureChanged(bool is_picture_in_picture) override;
void Wait(); void Wait();
private: private:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment