Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Add E2E test of audio player #10441

Merged
merged 75 commits into from
Apr 6, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
4dcc8e7
Add audio-player.spec.ts
luixxiul Mar 19, 2023
1694921
Download audio file
luixxiul Mar 19, 2023
ddc7898
Reply
luixxiul Mar 19, 2023
b8facfe
ReplyChain
luixxiul Mar 19, 2023
f88ff9c
Audio player on a thread
luixxiul Mar 19, 2023
133cf69
Add 'wrapper' option to takeSnapshots() in mx_ThreadView
luixxiul Mar 23, 2023
2e55e28
Click timestamps to highlight mx_EventTile to hopefully avoid flaky P…
luixxiul Mar 23, 2023
f2a6d0a
Assert that the radio button for light theme was checked
luixxiul Mar 24, 2023
c6cf476
Typo
luixxiul Mar 24, 2023
f23cfc2
Update cypress/e2e/audio-player/audio-player.spec.ts
luixxiul Mar 24, 2023
617f979
Update cypress/e2e/audio-player/audio-player.spec.ts
luixxiul Mar 24, 2023
b282fff
Update cypress/e2e/audio-player/audio-player.spec.ts
luixxiul Mar 24, 2023
c6b908d
Update cypress/e2e/audio-player/audio-player.spec.ts
luixxiul Mar 24, 2023
f0b120e
Update cypress/e2e/audio-player/audio-player.spec.ts
luixxiul Mar 24, 2023
495b612
Add comments to const percyCSS
luixxiul Mar 25, 2023
649d20b
Remove double quotation marks inside backticks
luixxiul Mar 25, 2023
445be1d
Rename a test
luixxiul Mar 25, 2023
3742b4f
Rename a test and edit a comment on mx_ReplyChain
luixxiul Mar 25, 2023
f6ffc1a
Wait until rendering of the player settled and assert that the play b…
luixxiul Mar 25, 2023
b18794d
Extract the test for IRC layout
luixxiul Mar 25, 2023
36b650e
Add and edit comments for takeSnapshots() and the test on IRC layout
luixxiul Mar 25, 2023
399a434
Move comments about snapshot widths
luixxiul Mar 25, 2023
fa97ee6
Check audio player's rendering and its button's visibility
luixxiul Mar 25, 2023
725d020
Add checkPlayerVisibility()
luixxiul Mar 25, 2023
82e4804
Take snapshots of the small player
luixxiul Mar 26, 2023
bcf8634
Edit snapshot name
luixxiul Mar 26, 2023
376ef1b
Use cy.closeDialog()
luixxiul Mar 26, 2023
6d559f0
Check player visibility on ThreadView
luixxiul Mar 26, 2023
1e0560c
Manage widths with variables
luixxiul Mar 26, 2023
39cdbe3
Merge branch 'develop' into test-audioplayer
luixxiul Mar 26, 2023
8ff182a
Remove 'takeSnapshotTimeline'
luixxiul Mar 26, 2023
b148eb8
Update cypress/e2e/audio-player/audio-player.spec.ts
luixxiul Mar 27, 2023
f4a0ee5
Update cypress/e2e/audio-player/audio-player.spec.ts
luixxiul Mar 27, 2023
e8094bd
Update cypress/e2e/audio-player/audio-player.spec.ts
luixxiul Mar 27, 2023
6b496e8
Edit comments
luixxiul Mar 27, 2023
98dd473
Remove an obsolete comment
luixxiul Mar 27, 2023
1a0fde5
Remove a command to set a layout value
luixxiul Mar 27, 2023
1b279fd
Remove a command to enable use_system_theme
luixxiul Mar 27, 2023
698f443
Revert "Remove a command to enable use_system_theme"
luixxiul Mar 29, 2023
437ee52
Edit a comment - disable system theme
luixxiul Mar 29, 2023
a59586f
Merge branch 'develop' of https://github.com/matrix-org/matrix-react-…
luixxiul Mar 31, 2023
555f5de
Edit a comment
luixxiul Apr 1, 2023
cdc77d6
Remove an assertion about the audio player being rendered
luixxiul Apr 1, 2023
946b330
Edit a test on a thread
luixxiul Apr 1, 2023
c581aae
Use Cypress Testing Library
luixxiul Mar 31, 2023
6969e5a
Use existing functions in favor of visitRoom()
luixxiul Apr 1, 2023
af07043
Improve the test flow - checking on the high contrast theme
luixxiul Apr 1, 2023
04ad2f8
Simplify and improve the widths setting of snapshots
luixxiul Apr 1, 2023
a20648f
Improve takeSnapshots
luixxiul Apr 1, 2023
dd1d306
Improve the test - checking a reply and a reply chain
luixxiul Apr 1, 2023
6495655
Remove redundant within()
luixxiul Apr 1, 2023
7774d44
Add audio files to make the test check files more strictly
luixxiul Apr 1, 2023
5dc2463
Simplify the test a little bit by removing within()
luixxiul Apr 1, 2023
3c5bb25
Edit a comment
luixxiul Apr 1, 2023
7488d88
Create uploadAndTakeSnapshots()
luixxiul Apr 1, 2023
a9fc678
Improve the test - download
luixxiul Apr 1, 2023
21d0798
lint
luixxiul Apr 1, 2023
b11f30d
theme -> detail
luixxiul Apr 1, 2023
7019c86
Merge branch 'develop' of https://github.com/matrix-org/matrix-react-…
luixxiul Apr 1, 2023
b176a22
Iterate - remove uploadAndTakeSnapshots
luixxiul Apr 2, 2023
50a0c1a
Iterate - remove within()
luixxiul Apr 2, 2023
0175351
Iterate - remove redundant wrappers
luixxiul Apr 2, 2023
e2e08b3
Output log for IRC layout
luixxiul Apr 2, 2023
f3fc364
Remove redundant comments
luixxiul Apr 2, 2023
b38ee4d
Edit log()
luixxiul Apr 2, 2023
df5f2b9
Chain commands
luixxiul Apr 2, 2023
bf296a4
Edit comments
luixxiul Apr 2, 2023
d95b153
Merge branch 'develop' of https://github.com/matrix-org/matrix-react-…
luixxiul Apr 3, 2023
c1baa6d
Remove unused injectAxe()
luixxiul Apr 3, 2023
c0d9733
Merge branch 'develop' into test-audioplayer
luixxiul Apr 5, 2023
7d0df71
Add a comment about 'monospace'
luixxiul Apr 5, 2023
e1ae92b
Edit a comment
luixxiul Apr 5, 2023
febe45b
Merge branch 'develop' into test-audioplayer
richvdh Apr 5, 2023
4c9c613
Merge branch 'develop' into test-audioplayer
luixxiul Apr 5, 2023
450a48f
Merge branch 'develop' into test-audioplayer
t3chguy Apr 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
235 changes: 235 additions & 0 deletions cypress/e2e/audio-player/audio-player.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
/*
Copyright 2023 Suguru Hirahara

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/// <reference types="cypress" />

import { HomeserverInstance } from "../../plugins/utils/homeserver";
import { SettingLevel } from "../../../src/settings/SettingLevel";
import { Layout } from "../../../src/settings/enums/Layout";

describe("Audio player", () => {
let homeserver: HomeserverInstance;
let roomId: string;

// FIXME: hide mx_SeekBar because flaky - see https://github.com/vector-im/element-web/issues/24898
const percyCSS = ".mx_SeekBar { visibility: hidden !important; }";

const visitRoom = () => {
cy.visit("/#/room/" + roomId);
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.Group);

// Wait until configuration is finished
cy.contains(
".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group'] .mx_GenericEventListSummary_summary",
"created and configured the room.",
).should("exist");
};

const uploadFile = (file: string) => {
// Upload a file from the message composer
cy.get(".mx_MessageComposer_actions input[type='file']").selectFile(file, { force: true });

cy.get(".mx_Dialog").within(() => {
// Click "Upload" button
cy.get("[data-testid='dialog-primary-button']").should("have.text", "Upload").click();
});

// Wait until the file is sent
cy.get(".mx_RoomView_statusArea_expanded").should("not.exist");
cy.get(".mx_EventTile.mx_EventTile_last .mx_EventTile_receiptSent").should("exist");
};

const checkPlayerFilenameLong = () => {
luixxiul marked this conversation as resolved.
Show resolved Hide resolved
// Detect the audio file
cy.get(".mx_EventTile_mediaLine .mx_MAudioBody").within(() => {
// Assert that the audio player is rendered
cy.get(".mx_AudioPlayer_container").within(() => {
// Assert that media information is rendered
cy.get(".mx_AudioPlayer_mediaInfo").within(() => {
cy.get(".mx_AudioPlayer_mediaName").should("have.text", "1sec-long-name-audio-file.ogg");
cy.contains(".mx_AudioPlayer_byline", "00:01").should("exist");
cy.contains(".mx_AudioPlayer_byline", "(3.56 KB)").should("exist"); // actual size
});

// Assert that the play button is rendered
cy.get("[data-testid='play-pause-button'][aria-label='Play']").should("exist");
});
});
};

// Take snapshots in modern and bubble layout, outputting log for reference/debugging
// Player on IRC layout should have the same layout as group layout
luixxiul marked this conversation as resolved.
Show resolved Hide resolved
const takeSnapshots = (detail: string) => {
// Check the status of the seek bar
// TODO: check if visible - currently visibility check on a narrow timeline causes an error
cy.get(".mx_AudioPlayer_seek input[type='range']").should("exist");

// Assert that the pause button is not rendered
cy.get("[data-testid='play-pause-button'][aria-label='Pause']").should("not.exist");

// Assert that the play button is rendered
cy.get("[data-testid='play-pause-button'][aria-label='Play']").should("exist");

// Enable group layout
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.Group);

// 243 + 12px + 12px = 267px
// See _MediaBody.pcss and _AudioPlayer.pcss for spacing
cy.get(".mx_MAudioBody").percySnapshotElement(detail + " on group layout", {
percyCSS,
widths: [267],
});

cy.log("Took a snapshot of " + detail + " on group layout");

// Enable bubble layout
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.Bubble);

// 243px + 12px + 48px = 303px
// See _EventBubbleTile.pcss and _AudioPlayer.pcss for spacing
cy.get(".mx_MAudioBody").percySnapshotElement(detail + " on bubble layout", {
percyCSS,
widths: [303],
});

cy.log("Took a snapshot of " + detail + " on bubble layout");

// Reset the layout
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.Group);
};

beforeEach(() => {
cy.startHomeserver("default").then((data) => {
homeserver = data;
cy.initTestUser(homeserver, "Hanako").then(() =>
cy.createRoom({}).then((_roomId) => {
roomId = _roomId;
}),
);
});

cy.injectAxe();
});

afterEach(() => {
cy.stopHomeserver(homeserver);
});

it("should render player on every layout", () => {
luixxiul marked this conversation as resolved.
Show resolved Hide resolved
visitRoom();

// Upload one second audio file with a long file name
uploadFile("cypress/fixtures/1sec-long-name-audio-file.ogg");

cy.get(".mx_RoomView_MessageList").within(() => {
checkPlayerFilenameLong();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this necessary? it seems it doesn't matter if the audio player is rendered before we change layout?

Likewise below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention of it was to ensure that the audio player renders every information properly, but it indeed seems checkPlayerFilenameLong itself is no longer necessary / relevant because Percy checks a visual regression. What would you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that if you're going to check it, you should check it after we change layout - otherwise there is no difference between the tests.

It may not be entirely necessary because of the Percy check, but I think it is harmless.


// Check audio player on IRC layout here, which currently should be same as on modern layout
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.IRC);
// 243 + 12px + 12px = 267px
// See _MediaBody.pcss and _AudioPlayer.pcss for spacing
cy.get(".mx_MAudioBody").percySnapshotElement("Audio player (light theme) on IRC layout", {
percyCSS,
widths: [267],
});
cy.log("Took a snapshot of Audio player (light theme) on IRC layout");
richvdh marked this conversation as resolved.
Show resolved Hide resolved

// Reset to the default layout
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.Group);
richvdh marked this conversation as resolved.
Show resolved Hide resolved

// Take snapshots (light theme)
takeSnapshots("Audio player (light theme)");

// Take snapshots (light theme, monospace font)
cy.setSettingValue("useSystemFont", null, SettingLevel.DEVICE, true);
cy.setSettingValue("systemFont", null, SettingLevel.DEVICE, "monospace");
// Assert that the monospace timer is visible
cy.get("[role='timer']").should("have.css", "font-family", '"monospace"').should("be.visible");
takeSnapshots("Audio player (light theme, monospace)");

// Reset font setting
cy.setSettingValue("useSystemFont", null, SettingLevel.DEVICE, false);

// Take snapshots (dark theme)
cy.setSettingValue("theme", null, SettingLevel.ACCOUNT, "dark");
takeSnapshots("Audio player (dark theme)");
});
});

it("should render player on high contrast theme", () => {
visitRoom();

// Upload one second audio file with a long file name
uploadFile("cypress/fixtures/1sec-long-name-audio-file.ogg");

cy.get(".mx_RoomView_MessageList").within(() => {
checkPlayerFilenameLong();
});

// Enable high contrast manually
cy.openUserSettings("Appearance");
cy.get(".mx_UserSettingsDialog").within(() => {
cy.get(".mx_ThemeChoicePanel").within(() => {
cy.get("[data-testid='theme-choice-panel-selectors']").within(() => {
// Enable light theme
cy.get(".mx_ThemeSelector_light").click();
});

cy.get("[data-testid='theme-choice-panel-highcontrast']").within(() => {
// Click the checkbox
cy.get("label .mx_Checkbox_background").click();
});
});

// Close the user settings dialog
cy.get("[aria-label='Close dialog']").click();
});

// Take snapshots (high contrast, light theme only)
cy.get(".mx_RoomView_MessageList").within(() => {
takeSnapshots("Audio player (high contrast)");
});
});

it("should play an audio file", () => {
visitRoom();

// Upload an audio file
uploadFile("cypress/fixtures/1sec.ogg");

cy.get(".mx_RoomView_MessageList").within(() => {
cy.get(".mx_EventTile_mediaLine .mx_MAudioBody").within(() => {
// Assert that the audio player is rendered
cy.get(".mx_AudioPlayer_container").within(() => {
// Assert that the counter is zero before clicking the play button
cy.contains(".mx_AudioPlayer_seek [role='timer']", "00:00").should("exist");

// Click the play button
cy.get("[data-testid='play-pause-button'][aria-label='Play']").click();

// Assert that the pause button is rendered
cy.get("[data-testid='play-pause-button'][aria-label='Pause']").should("exist");

// Assert that the timer is reset when the audio file finished playing
cy.contains(".mx_AudioPlayer_seek [role='timer']", "00:00").should("exist");

// Assert that the play button is rendered
cy.get("[data-testid='play-pause-button'][aria-label='Play']").should("exist");
});
});
});
});
});
Binary file added cypress/fixtures/1sec-long-name-audio-file.ogg
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Binary file not shown.
4 changes: 2 additions & 2 deletions src/components/views/settings/ThemeChoicePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export default class ThemeChoicePanel extends React.Component<IProps, IState> {
(findHighContrastTheme(this.state.theme) || isHighContrastTheme(this.state.theme))
) {
return (
<div>
<div data-testid="theme-choice-panel-highcontrast">
<StyledCheckbox
checked={isHighContrastTheme(this.state.theme)}
onChange={(e) => this.highContrastThemeChanged(e.target.checked)}
Expand Down Expand Up @@ -248,7 +248,7 @@ export default class ThemeChoicePanel extends React.Component<IProps, IState> {
<div className="mx_SettingsTab_section mx_ThemeChoicePanel">
<span className="mx_SettingsTab_subheading">{_t("Theme")}</span>
{systemThemeSection}
<div className="mx_ThemeSelectors">
<div className="mx_ThemeSelectors" data-testid="theme-choice-panel-selectors">
<StyledRadioGroup
name="theme"
definitions={orderedThemes.map((t) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ exports[`ThemeChoicePanel renders the theme choice UI 1`] = `
</span>
<div
class="mx_ThemeSelectors"
data-testid="theme-choice-panel-selectors"
>
<label
class="mx_StyledRadioButton mx_ThemeSelector_light mx_StyledRadioButton_disabled mx_StyledRadioButton_outlined"
Expand Down