Move AudioPlayer to shared components (#30386)
* feat: add `PlayPauseButton` to storybook * feat: add generic media body * feat: add seekbar component * chore: add ViewWrapper to help writing stories with vm * refactor: move `formatBytes` from `formattingUtils` into shared component * refactor: add `className` props to `Clock` * feat: add new audio player component * test(e2e): add screenshots for new shared components * feat: add AudioPlayerViewModel * feat: use new audio player in `MAudioBody` * refactor: remove old audio player * test(e2e): update existing tests * refactor: remove unused `DurationClock` * refactor: rename `SeekBar` into `LegacySeekBar`
This commit is contained in:
@@ -40,7 +40,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
// wait for the tile to finish loading
|
||||
await expect(
|
||||
page
|
||||
.locator(".mx_AudioPlayer_mediaName")
|
||||
.getByTestId("audio-player-name")
|
||||
.last()
|
||||
.filter({ hasText: file.split("/").at(-1) }),
|
||||
).toBeVisible();
|
||||
@@ -55,12 +55,10 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
// Check that the audio player is rendered and its button becomes visible
|
||||
const checkPlayerVisibility = async (locator: Locator) => {
|
||||
// Assert that the audio player and media information are visible
|
||||
const mediaInfo = locator.locator(
|
||||
".mx_EventTile_mediaLine .mx_MAudioBody .mx_AudioPlayer_container .mx_AudioPlayer_mediaInfo",
|
||||
);
|
||||
await expect(mediaInfo.locator(".mx_AudioPlayer_mediaName", { hasText: ".ogg" })).toBeVisible(); // extension
|
||||
await expect(mediaInfo.locator(".mx_AudioPlayer_byline", { hasText: "00:01" })).toBeVisible();
|
||||
await expect(mediaInfo.locator(".mx_AudioPlayer_byline", { hasText: "(3.56 KB)" })).toBeVisible(); // actual size
|
||||
const mediaInfo = locator.getByRole("region", { name: "Audio player" });
|
||||
await expect(mediaInfo.getByText(".ogg")).toBeVisible(); // extension
|
||||
await expect(mediaInfo.getByRole("time")).toHaveText("00:01"); // duration
|
||||
await expect(mediaInfo.getByText("(3.56 KB)")).toBeVisible(); // actual size;
|
||||
|
||||
// Assert that the play button can be found and is visible
|
||||
await expect(locator.getByRole("button", { name: "Play" })).toBeVisible();
|
||||
@@ -79,7 +77,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
}
|
||||
|
||||
// Check the status of the seek bar
|
||||
expect(await page.locator(".mx_AudioPlayer_seek input[type='range']").count()).toBeGreaterThan(0);
|
||||
expect(await page.getByRole("region", { name: "Audio player" }).getByRole("slider").count()).toBeGreaterThan(0);
|
||||
|
||||
// Enable IRC layout
|
||||
await app.settings.setValue("layout", null, SettingLevel.DEVICE, Layout.IRC);
|
||||
@@ -101,7 +99,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
display: none !important;
|
||||
}
|
||||
`,
|
||||
mask: [page.locator(".mx_AudioPlayer_seek")],
|
||||
mask: [page.getByTestId("audio-player-seek")],
|
||||
};
|
||||
|
||||
// Take a snapshot of mx_EventTile_last on IRC layout
|
||||
@@ -187,9 +185,9 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
await uploadFile(page, "playwright/sample-files/1sec.ogg");
|
||||
|
||||
// Assert that the audio player is rendered
|
||||
const container = page.locator(".mx_EventTile_last .mx_AudioPlayer_container");
|
||||
const container = page.locator(".mx_EventTile_last").getByRole("region", { name: "Audio player" });
|
||||
// Assert that the counter is zero before clicking the play button
|
||||
await expect(container.locator(".mx_AudioPlayer_seek [role='timer']", { hasText: "00:00" })).toBeVisible();
|
||||
await expect(container.getByRole("timer")).toHaveText("00:00");
|
||||
|
||||
// Find and click "Play" button, the wait is to make the test less flaky
|
||||
await expect(container.getByRole("button", { name: "Play" })).toBeVisible();
|
||||
@@ -199,7 +197,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
await expect(container.getByRole("button", { name: "Pause" })).toBeVisible();
|
||||
|
||||
// Assert that the timer is reset when the audio file finished playing
|
||||
await expect(container.locator(".mx_AudioPlayer_seek [role='timer']", { hasText: "00:00" })).toBeVisible();
|
||||
await expect(container.getByRole("timer")).toHaveText("00:00");
|
||||
|
||||
// Assert that "Play" button can be found
|
||||
await expect(container.getByRole("button", { name: "Play" })).toBeVisible();
|
||||
@@ -227,7 +225,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
await uploadFile(page, "playwright/sample-files/1sec.ogg");
|
||||
|
||||
// Assert the audio player is rendered
|
||||
await expect(page.locator(".mx_EventTile_last .mx_AudioPlayer_container")).toBeVisible();
|
||||
await expect(page.getByRole("region", { name: "Audio player" })).toBeVisible();
|
||||
|
||||
// Find and click "Reply" button on MessageActionBar
|
||||
const tile = page.locator(".mx_EventTile_last");
|
||||
@@ -237,7 +235,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
await uploadFile(page, "playwright/sample-files/1sec.ogg");
|
||||
|
||||
// Assert that the audio player is rendered
|
||||
await expect(tile.locator(".mx_AudioPlayer_container")).toBeVisible();
|
||||
await expect(tile.getByRole("region", { name: "Audio player" })).toBeVisible();
|
||||
|
||||
// Assert that replied audio file is rendered as file button inside ReplyChain
|
||||
const button = tile.locator(".mx_ReplyChain_wrapper .mx_MFileBody_info[role='button']");
|
||||
@@ -262,7 +260,9 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
await uploadFile(page, "playwright/sample-files/upload-first.ogg");
|
||||
|
||||
// Assert that the audio player is rendered
|
||||
await expect(page.locator(".mx_EventTile_last .mx_AudioPlayer_container")).toBeVisible();
|
||||
await expect(
|
||||
page.locator(".mx_EventTile_last").getByRole("region", { name: "Audio player" }),
|
||||
).toBeVisible();
|
||||
|
||||
await clickButtonReply(tile);
|
||||
|
||||
@@ -270,7 +270,9 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
await uploadFile(page, "playwright/sample-files/upload-second.ogg");
|
||||
|
||||
// Assert that the audio player is rendered
|
||||
await expect(page.locator(".mx_EventTile_last .mx_AudioPlayer_container")).toBeVisible();
|
||||
await expect(
|
||||
page.locator(".mx_EventTile_last").getByRole("region", { name: "Audio player" }),
|
||||
).toBeVisible();
|
||||
|
||||
await clickButtonReply(tile);
|
||||
|
||||
@@ -278,7 +280,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
await uploadFile(page, "playwright/sample-files/upload-third.ogg");
|
||||
|
||||
// Assert that the audio player is rendered
|
||||
await expect(tile.locator(".mx_AudioPlayer_container")).toBeVisible();
|
||||
await expect(tile.getByRole("region", { name: "Audio player" })).toBeVisible();
|
||||
|
||||
// Assert that there are two "mx_ReplyChain" elements
|
||||
await expect(tile.locator(".mx_ReplyChain")).toHaveCount(2);
|
||||
@@ -314,7 +316,9 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
// On the main timeline
|
||||
const messageList = page.locator(".mx_RoomView_MessageList");
|
||||
// Assert the audio player is rendered
|
||||
await expect(messageList.locator(".mx_EventTile_last .mx_AudioPlayer_container")).toBeVisible();
|
||||
await expect(
|
||||
messageList.locator(".mx_EventTile_last").getByRole("region", { name: "Audio player" }),
|
||||
).toBeVisible();
|
||||
// Find and click "Reply in thread" button
|
||||
await messageList.locator(".mx_EventTile_last").hover();
|
||||
await messageList.locator(".mx_EventTile_last").getByRole("button", { name: "Reply in thread" }).click();
|
||||
@@ -322,10 +326,10 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
// On a thread
|
||||
const thread = page.locator(".mx_ThreadView");
|
||||
const threadTile = thread.locator(".mx_EventTile_last");
|
||||
const audioPlayer = threadTile.locator(".mx_AudioPlayer_container");
|
||||
const audioPlayer = threadTile.getByRole("region", { name: "Audio player" });
|
||||
|
||||
// Assert that the counter is zero before clicking the play button
|
||||
await expect(audioPlayer.locator(".mx_AudioPlayer_seek [role='timer']", { hasText: "00:00" })).toBeVisible();
|
||||
await expect(audioPlayer.getByRole("timer")).toHaveText("00:00");
|
||||
|
||||
// Find and click "Play" button, the wait is to make the test less flaky
|
||||
await expect(audioPlayer.getByRole("button", { name: "Play" })).toBeVisible();
|
||||
@@ -335,7 +339,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
await expect(audioPlayer.getByRole("button", { name: "Pause" })).toBeVisible();
|
||||
|
||||
// Assert that the timer is reset when the audio file finished playing
|
||||
await expect(audioPlayer.locator(".mx_AudioPlayer_seek [role='timer']", { hasText: "00:00" })).toBeVisible();
|
||||
await expect(audioPlayer.getByRole("timer")).toHaveText("00:00");
|
||||
|
||||
// Assert that "Play" button can be found
|
||||
await expect(audioPlayer.getByRole("button", { name: "Play" })).not.toBeDisabled();
|
||||
|
||||
@@ -63,9 +63,7 @@ test.describe("FilePanel", () => {
|
||||
await expect(roomViewBody.locator(".mx_EventTile[data-layout='group'] img[alt='riot.png']")).toBeVisible();
|
||||
|
||||
// Assert that the audio player is rendered
|
||||
await expect(
|
||||
roomViewBody.locator(".mx_EventTile[data-layout='group'] .mx_AudioPlayer_container"),
|
||||
).toBeVisible();
|
||||
await expect(roomViewBody.getByRole("region", { name: "Audio player" })).toBeVisible();
|
||||
|
||||
// Assert that the file button exists
|
||||
await expect(
|
||||
@@ -97,9 +95,7 @@ test.describe("FilePanel", () => {
|
||||
await expect(image.locator("img[alt='riot.png']")).toBeVisible();
|
||||
|
||||
// Detect the audio file
|
||||
const audio = filePanelMessageList.locator(
|
||||
".mx_EventTile_mediaLine .mx_MAudioBody .mx_AudioPlayer_container",
|
||||
);
|
||||
const audio = filePanelMessageList.getByRole("region", { name: "Audio player" });
|
||||
// Assert that the play button is rendered
|
||||
await expect(audio.getByRole("button", { name: "Play" })).toBeVisible();
|
||||
|
||||
@@ -130,7 +126,7 @@ test.describe("FilePanel", () => {
|
||||
// Take a snapshot of file tiles list on FilePanel
|
||||
await expect(filePanelMessageList).toMatchScreenshot("file-tiles-list.png", {
|
||||
// Exclude timestamps & flaky seek bar from snapshot
|
||||
mask: [page.locator(".mx_MessageTimestamp, .mx_AudioPlayer_seek")],
|
||||
mask: [page.locator(".mx_MessageTimestamp"), page.getByTestId("audio-player-seek")],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -138,21 +134,19 @@ test.describe("FilePanel", () => {
|
||||
// Upload an image file
|
||||
await uploadFile(page, "playwright/sample-files/1sec.ogg");
|
||||
|
||||
const audioBody = page.locator(
|
||||
".mx_FilePanel .mx_RoomView_MessageList .mx_EventTile_mediaLine .mx_MAudioBody .mx_AudioPlayer_container",
|
||||
);
|
||||
const audioBody = page.getByTestId("right-panel").getByRole("region", { name: "Audio player" });
|
||||
|
||||
// Assert that the audio player is rendered
|
||||
// Assert that the audio file information is rendered
|
||||
const mediaInfo = audioBody.locator(".mx_AudioPlayer_mediaInfo");
|
||||
await expect(mediaInfo.locator(".mx_AudioPlayer_mediaName").getByText("1sec.ogg")).toBeVisible();
|
||||
await expect(mediaInfo.locator(".mx_AudioPlayer_byline", { hasText: "00:01" })).toBeVisible();
|
||||
await expect(mediaInfo.locator(".mx_AudioPlayer_byline", { hasText: "(3.56 KB)" })).toBeVisible(); // actual size
|
||||
// Assert that the audio file information is rendered;
|
||||
await expect(audioBody.getByText("1sec.ogg")).toBeVisible(); // extension
|
||||
await expect(audioBody.getByRole("time")).toHaveText("00:01"); // duration
|
||||
await expect(audioBody.getByText("(3.56 KB)")).toBeVisible(); // actual size;
|
||||
|
||||
// Assert that the duration counter is 00:01 before clicking the play button
|
||||
await expect(audioBody.locator(".mx_AudioPlayer_mediaInfo time", { hasText: "00:01" })).toBeVisible();
|
||||
await expect(audioBody.getByRole("time")).toHaveText("00:01");
|
||||
|
||||
// Assert that the counter is zero before clicking the play button
|
||||
await expect(audioBody.locator(".mx_AudioPlayer_seek [role='timer']", { hasText: "00:00" })).toBeVisible();
|
||||
await expect(audioBody.getByRole("timer")).toHaveText("00:00");
|
||||
|
||||
// Click the play button
|
||||
await audioBody.getByRole("button", { name: "Play" }).click();
|
||||
@@ -161,7 +155,7 @@ test.describe("FilePanel", () => {
|
||||
await expect(audioBody.getByRole("button", { name: "Pause" })).toBeVisible();
|
||||
|
||||
// Assert that the timer is reset when the audio file finished playing
|
||||
await expect(audioBody.locator(".mx_AudioPlayer_seek [role='timer']", { hasText: "00:00" })).toBeVisible();
|
||||
await expect(audioBody.getByRole("timer")).toHaveText("00:00");
|
||||
|
||||
// Assert that the play button is rendered
|
||||
await expect(audioBody.getByRole("button", { name: "Play" })).toBeVisible();
|
||||
|
||||
Reference in New Issue
Block a user