Fix unit tests

This commit is contained in:
Timo K
2026-04-15 15:51:21 +02:00
parent 486b3ea45d
commit 3fc823e049
5 changed files with 30 additions and 42 deletions
+4 -4
View File
@@ -164,7 +164,7 @@ export const LoudspeakerButton: FC<LoudspeakerButtonProps> = ({
); );
}; };
function classNamesForScrrenWidth( function classNamesForScreenWidth(
className?: string, className?: string,
forScreenWidth?: "wide" | "narrow", forScreenWidth?: "wide" | "narrow",
): string { ): string {
@@ -190,10 +190,10 @@ export const SettingsIconButton: FC<SettingsIconButtonProps> = ({
return ( return (
<Tooltip label={t("common.settings")}> <Tooltip label={t("common.settings")}>
<IconButton <IconButton
className={classNamesForScrrenWidth(className, showForScreenWidth)} className={classNamesForScreenWidth(className, showForScreenWidth)}
{...props} {...props}
> >
<Icon aria-hidden/> <Icon aria-hidden />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
); );
@@ -213,7 +213,7 @@ export const SettingsButton: FC<SettingsButtonProps> = ({
return ( return (
<Tooltip label={t("common.settings")}> <Tooltip label={t("common.settings")}>
<CpdButton <CpdButton
className={classNamesForScrrenWidth(className, showForScreenWidth)} className={classNamesForScreenWidth(className, showForScreenWidth)}
iconOnly iconOnly
Icon={ Icon={
platform === "android" ? OverflowVerticalIcon : OverflowHorizontalIcon platform === "android" ? OverflowVerticalIcon : OverflowHorizontalIcon
+2
View File
@@ -114,6 +114,7 @@ export const CallFooter: FC<FooterProps> = ({
key="settings" key="settings"
showForScreenWidth="narrow" showForScreenWidth="narrow"
onClick={openSettings} onClick={openSettings}
data-testid="settings-bottom-center"
/>, />,
); );
} }
@@ -222,6 +223,7 @@ export const CallFooter: FC<FooterProps> = ({
kind="secondary" kind="secondary"
showForScreenWidth="wide" showForScreenWidth="wide"
onClick={openSettings} onClick={openSettings}
data-testid="settings-bottom-left"
/> />
)} )}
{children} {children}
+15 -12
View File
@@ -44,7 +44,6 @@ import { type MediaDevices as ECMediaDevices } from "../state/MediaDevices";
import { constant } from "../state/Behavior"; import { constant } from "../state/Behavior";
import { AppBar } from "../AppBar"; import { AppBar } from "../AppBar";
import { initializeWidget } from "../widget"; import { initializeWidget } from "../widget";
import callFooterStyles from "../components/CallFooter.module.css";
initializeWidget(); initializeWidget();
vi.hoisted( vi.hoisted(
@@ -123,7 +122,7 @@ function createInCallView(args: CreateInCallViewArgs = {}): RenderResult & {
[local, alice], [local, alice],
undefined, undefined,
mediaDevices, mediaDevices,
{}, args.callViewModelOptions,
); );
rtcSession.joined = true; rtcSession.joined = true;
@@ -191,7 +190,7 @@ describe("InCallView", () => {
}); });
}); });
describe("settings button with AppBar header", () => { describe("settings button with AppBar header", () => {
it("is accessible when showHeader is false", () => { it("mobile landscape, is accessible when showHeader is false", () => {
// windowSize with height <= 600 results in "flat" windowMode, // windowSize with height <= 600 results in "flat" windowMode,
// which means showHeader$ emits false. // which means showHeader$ emits false.
const { getAllByRole } = createInCallView({ const { getAllByRole } = createInCallView({
@@ -204,20 +203,20 @@ describe("InCallView", () => {
}); });
// When showHeader is false, hideSettingsButton is false, // When showHeader is false, hideSettingsButton is false,
// so the settings button is visible in the footer. // so the settings button is visible in the footer.
const settingsBtns = getAllByRole("button", { name: "Settings" }); const settingsBtn = getAllByRole("button", { name: "Settings" });
expect(settingsBtns.length).toBe(2);
const [btnA, btnB] = settingsBtns;
// here we check for two settings buttons because there are two buttons in the bottom bar. One for the // here we check for two settings buttons because there are two buttons in the bottom bar. One for the
// the narrow layout and another one for the wide layout. // the narrow layout and another one for the wide layout.
// Their visibility uses @media css queries, which cannot be tested in JSDOM, // Their visibility uses @media css queries, which cannot be tested in JSDOM,
// but we can at least check that both buttons are rendered and have the correct classes. // but we can at least check that both buttons are rendered and have the correct classes.
expect(btnA).toBeInTheDocument(); expect(settingsBtn.length).toBe(2);
expect(btnA).toHaveClass(callFooterStyles.settingsOnlyShowWide); expect(settingsBtn[0]).toHaveAttribute(
expect(btnB).toBeInTheDocument(); "data-testid",
expect(btnB).toHaveClass(callFooterStyles.settingsOnlyShowNarrow); "settings-bottom-left",
);
expect(settingsBtn[0]).toBeVisible();
}); });
it("is accessible when showHeader is true", () => { it("mobile portrait, is accessible when showHeader is true", () => {
// windowSize with height > 600 and width > 600 results in "normal" windowMode, // windowSize with height > 600 and width > 600 results in "normal" windowMode,
// which means showHeader$ emits true. // which means showHeader$ emits true.
const { getAllByRole } = createInCallView({ const { getAllByRole } = createInCallView({
@@ -232,8 +231,12 @@ describe("InCallView", () => {
// hideSettingsButton is true in the footer, but the settings // hideSettingsButton is true in the footer, but the settings
// button is rendered in the AppBar via useAppBarSecondaryButton. // button is rendered in the AppBar via useAppBarSecondaryButton.
const settingsBtns = getAllByRole("button", { name: "Settings" }); const settingsBtns = getAllByRole("button", { name: "Settings" });
expect(settingsBtns.length).toBe(1);
expect(settingsBtns.length).toBe(1);
expect(settingsBtns[0]).toHaveAttribute(
"data-testid",
"settings-app-bar",
);
expect(settingsBtns[0]).toBeVisible(); expect(settingsBtns[0]).toBeVisible();
}); });
}); });
+5 -1
View File
@@ -565,7 +565,11 @@ export const InCallView: FC<InCallViewProps> = ({
const settingsButtonInAppBar = const settingsButtonInAppBar =
headerStyle === HeaderStyle.AppBar && showHeader; headerStyle === HeaderStyle.AppBar && showHeader;
useAppBarSecondaryButton( useAppBarSecondaryButton(
<SettingsIconButton key="settings" onClick={openSettings} />, <SettingsIconButton
key="settings"
onClick={openSettings}
data-testid="settings-app-bar"
/>,
); );
// Only hide the settings button if we have an AppBar header and we are showing the header // Only hide the settings button if we have an AppBar header and we are showing the header
@@ -172,6 +172,7 @@ exports[`InCallView > rendering > renders 1`] = `
aria-labelledby="_r_8_" aria-labelledby="_r_8_"
class="_icon-button_1215g_8 settingsOnlyShowWide" class="_icon-button_1215g_8 settingsOnlyShowWide"
data-kind="secondary" data-kind="secondary"
data-testid="settings-bottom-left"
role="button" role="button"
style="--cpd-icon-button-size: 32px;" style="--cpd-icon-button-size: 32px;"
tabindex="0" tabindex="0"
@@ -307,6 +308,7 @@ exports[`InCallView > rendering > renders 1`] = `
class="_button_13vu4_8 settingsOnlyShowNarrow _has-icon_13vu4_60 _icon-only_13vu4_53" class="_button_13vu4_8 settingsOnlyShowNarrow _has-icon_13vu4_60 _icon-only_13vu4_53"
data-kind="secondary" data-kind="secondary"
data-size="lg" data-size="lg"
data-testid="settings-bottom-center"
role="button" role="button"
tabindex="0" tabindex="0"
> >
@@ -372,30 +374,7 @@ exports[`InCallView > rendering > renders 1`] = `
</svg> </svg>
</button> </button>
<button <button
aria-checked="false"
aria-labelledby="_r_s_" aria-labelledby="_r_s_"
class="_button_13vu4_8 shareScreen _has-icon_13vu4_60 _icon-only_13vu4_53"
data-kind="secondary"
data-size="lg"
data-testid="incall_screenshare"
role="switch"
tabindex="0"
>
<svg
aria-hidden="true"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1.288 20.713Q1.575 21 2 21h20q.424 0 .712-.288A.97.97 0 0 0 23 20a.97.97 0 0 0-.288-.712A.97.97 0 0 0 22 19H2a.97.97 0 0 0-.712.288A.97.97 0 0 0 1 20q0 .424.288.712m1.3-3.299A1.93 1.93 0 0 1 2 16V5q0-.824.587-1.412A1.93 1.93 0 0 1 4 3h16q.824 0 1.413.587Q22 4.176 22 5v11q0 .824-.587 1.413A1.93 1.93 0 0 1 20 18H4q-.824 0-1.412-.587m10.12-10.12a1 1 0 0 0-1.415 0l-2.5 2.5a1 1 0 0 0 1.414 1.414l.793-.793V13a1 1 0 1 0 2 0v-2.586l.793.793a1 1 0 0 0 1.414-1.414z"
/>
</svg>
</button>
<button
aria-labelledby="_r_11_"
class="_button_13vu4_8 endCall _has-icon_13vu4_60 _icon-only_13vu4_53 _destructive_13vu4_110" class="_button_13vu4_8 endCall _has-icon_13vu4_60 _icon-only_13vu4_53 _destructive_13vu4_110"
data-kind="primary" data-kind="primary"
data-size="lg" data-size="lg"
@@ -421,7 +400,7 @@ exports[`InCallView > rendering > renders 1`] = `
class="toggle layout" class="toggle layout"
> >
<input <input
aria-labelledby="_r_16_" aria-labelledby="_r_11_"
name="layout" name="layout"
type="radio" type="radio"
value="spotlight" value="spotlight"
@@ -439,7 +418,7 @@ exports[`InCallView > rendering > renders 1`] = `
/> />
</svg> </svg>
<input <input
aria-labelledby="_r_1b_" aria-labelledby="_r_16_"
checked="" checked=""
name="layout" name="layout"
type="radio" type="radio"