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 {
// Called when the metadata displayed in the container changes.
virtual void OnContainerMetadataChanged() = 0;
// Called when the action buttons in the container change.
virtual void OnContainerActionsChanged() = 0;
// Called when the container is clicked.
virtual void OnContainerClicked(const std::string& id) = 0;
......
......@@ -71,6 +71,7 @@ class MediaNotificationService
// MediaNotificationContainerObserver implementation.
void OnContainerExpanded(bool expanded) override {}
void OnContainerMetadataChanged() override {}
void OnContainerActionsChanged() override {}
void OnContainerClicked(const std::string& id) override;
void OnContainerDismissed(const std::string& id) override;
void OnContainerDestroyed(const std::string& id) override;
......
......@@ -131,6 +131,11 @@ void MediaDialogView::OnContainerMetadataChanged() {
observer.OnMediaSessionMetadataUpdated();
}
void MediaDialogView::OnContainerActionsChanged() {
for (auto& observer : observers_)
observer.OnMediaSessionActionsChanged();
}
void MediaDialogView::OnContainerDestroyed(const std::string& id) {
auto iter = observed_containers_.find(id);
DCHECK(iter != observed_containers_.end());
......
......@@ -43,6 +43,7 @@ class MediaDialogView : public views::BubbleDialogDelegateView,
// MediaNotificationContainerObserver implementation.
void OnContainerExpanded(bool expanded) override;
void OnContainerMetadataChanged() override;
void OnContainerActionsChanged() override;
void OnContainerClicked(const std::string& id) override {}
void OnContainerDismissed(const std::string& id) override {}
void OnContainerDestroyed(const std::string& id) override;
......
......@@ -55,6 +55,10 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver,
void OnMediaSessionMetadataUpdated() override { CheckDialogForText(); }
void OnMediaSessionActionsChanged() override {
CheckPictureInPictureButton();
}
// MediaToolbarButtonObserver implementation.
void OnMediaDialogOpened() override {
waiting_for_dialog_opened_ = false;
......@@ -106,6 +110,17 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver,
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:
void CheckDialogForText() {
if (!waiting_for_dialog_to_contain_text_)
......@@ -129,13 +144,25 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver,
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() {
if (!run_loop_)
return;
if (!waiting_for_dialog_opened_ && !waiting_for_button_shown_ &&
!waiting_for_dialog_to_contain_text_ &&
!waiting_for_notification_count_) {
!waiting_for_notification_count_ &&
!waiting_for_pip_visibility_changed_) {
run_loop_->Quit();
}
}
......@@ -165,6 +192,17 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver,
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() {
return MediaDialogView::GetDialogViewForTesting()
->GetNotificationsForTesting()
......@@ -177,11 +215,13 @@ class MediaToolbarButtonWatcher : public MediaToolbarButtonObserver,
bool waiting_for_dialog_opened_ = false;
bool waiting_for_button_shown_ = false;
bool waiting_for_notification_count_ = false;
bool waiting_for_pip_visibility_changed_ = false;
MediaDialogView* observed_dialog_ = nullptr;
bool waiting_for_dialog_to_contain_text_ = false;
base::string16 expected_text_;
int expected_notification_count_ = 0;
bool expected_pip_visibility_ = false;
DISALLOW_COPY_AND_ASSIGN(MediaToolbarButtonWatcher);
};
......@@ -345,6 +385,30 @@ class MediaDialogViewBrowserTest : public InProcessBrowserTest {
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() {
MediaToolbarButtonWatcher(GetToolbarIcon()).WaitForDialogOpened();
}
......@@ -360,6 +424,11 @@ class MediaDialogViewBrowserTest : public InProcessBrowserTest {
MediaToolbarButtonWatcher(GetToolbarIcon()).WaitForNotificationCount(count);
}
void WaitForPictureInPictureButtonVisibility(bool visible) {
MediaToolbarButtonWatcher(GetToolbarIcon())
.WaitForPictureInPictureButtonVisibility(visible);
}
void ClickPauseButtonOnDialog() {
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(MediaDialogView::IsShowing());
......@@ -372,6 +441,18 @@ class MediaDialogViewBrowserTest : public InProcessBrowserTest {
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) {
ASSERT_TRUE(MediaDialogView::IsShowing());
MediaNotificationContainerImplView* notification =
......@@ -570,3 +651,42 @@ IN_PROC_BROWSER_TEST_F(MediaDialogViewBrowserTest, ShowsCastSession) {
base::UTF8ToUTF16(route_description + " \xC2\xB7 " + sink_name));
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 {
// Called when a shown media session's metadata is updated.
virtual void OnMediaSessionMetadataUpdated() = 0;
// Called when a shown media session's actions are changed.
virtual void OnMediaSessionActionsChanged() = 0;
protected:
~MediaDialogViewObserver() override = default;
};
......
......@@ -226,6 +226,9 @@ void MediaNotificationContainerImplView::OnVisibleActionsChanged(
actions,
media_session::mojom::MediaSessionAction::kExitPictureInPicture));
ForceExpandedState();
for (auto& observer : observers_)
observer.OnContainerActionsChanged();
}
void MediaNotificationContainerImplView::OnMediaArtworkChanged(
......
......@@ -38,6 +38,7 @@ class MockMediaNotificationContainerObserver
// MediaNotificationContainerObserver implementation.
MOCK_METHOD1(OnContainerExpanded, void(bool expanded));
MOCK_METHOD0(OnContainerMetadataChanged, void());
MOCK_METHOD0(OnContainerActionsChanged, void());
MOCK_METHOD1(OnContainerClicked, void(const std::string& id));
MOCK_METHOD1(OnContainerDismissed, void(const std::string& id));
MOCK_METHOD1(OnContainerDestroyed, void(const std::string& id));
......
......@@ -39,6 +39,14 @@ function setupActionHandlers() {
navigator.mediaSession.setActionHandler('play', _ => { video.play(); });
navigator.mediaSession.setActionHandler('pause', _ => { video.pause(); });
}
function disablePictureInPicture() {
video.disablePictureInPicture = true;
}
function enablePictureInPicture() {
video.disablePictureInPicture = false;
}
</script>
</body>
</html>
......@@ -86,6 +86,10 @@ class COMPONENT_EXPORT(MEDIA_MESSAGE_CENTER) MediaNotificationViewImpl
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;
base::string16 GetSourceTitleForTesting() const;
......
......@@ -20,6 +20,17 @@ void MediaStartStopObserver::MediaStartedPlaying(const MediaPlayerInfo& info,
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(
const MediaPlayerInfo& info,
const MediaPlayerId& id,
......
......@@ -16,7 +16,12 @@ class WebContents;
// Used in tests to wait for media in a WebContents to start or stop playing.
class MediaStartStopObserver : public WebContentsObserver {
public:
enum class Type { kStart, kStop };
enum class Type {
kStart,
kStop,
kEnterPictureInPicture,
kExitPictureInPicture
};
MediaStartStopObserver(WebContents* web_contents, Type type);
~MediaStartStopObserver() override;
......@@ -29,6 +34,8 @@ class MediaStartStopObserver : public WebContentsObserver {
const MediaPlayerId& id,
WebContentsObserver::MediaStoppedReason reason) override;
void MediaPictureInPictureChanged(bool is_picture_in_picture) override;
void Wait();
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