Migrate some tests to React Testing Library (#9584)

This commit is contained in:
Germain 2022-11-18 09:16:11 +00:00 committed by GitHub
parent ef548a4843
commit 38dbe8ed33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 325 additions and 527 deletions

View file

@ -136,6 +136,7 @@ export default class SearchBox extends React.Component<IProps, IState> {
placeholder={this.state.blurred ? (blurredPlaceholder || placeholder) : placeholder}
autoComplete="off"
autoFocus={this.props.autoFocus}
data-testid="searchbox-input"
/>
{ clearButton }
</div>

View file

@ -15,12 +15,12 @@ limitations under the License.
*/
import React from "react";
// eslint-disable-next-line deprecate/import
import { mount, ReactWrapper } from "enzyme";
import { act } from "react-dom/test-utils";
import { MatrixEvent, EventType } from "matrix-js-sdk/src/matrix";
import { LocationAssetType, M_ASSET, M_LOCATION, M_TIMESTAMP } from "matrix-js-sdk/src/@types/location";
import { TEXT_NODE_TYPE } from "matrix-js-sdk/src/@types/extensible_events";
import { fireEvent, getByTestId, render, RenderResult, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import ForwardDialog from "../../../../src/components/views/dialogs/ForwardDialog";
@ -34,6 +34,7 @@ import {
mkEvent,
mkMessage,
mkStubRoom,
mockPlatformPeg,
} from "../../../test-utils";
import { TILE_SERVER_WK_KEY } from "../../../../src/utils/WellKnownUtils";
@ -71,24 +72,18 @@ describe("ForwardDialog", () => {
});
const defaultRooms = ["a", "A", "b"].map(name => mkStubRoom(name, name, mockClient));
const mountForwardDialog = async (message = defaultMessage, rooms = defaultRooms) => {
const mountForwardDialog = (message = defaultMessage, rooms = defaultRooms) => {
mockClient.getVisibleRooms.mockReturnValue(rooms);
mockClient.getRoom.mockImplementation(roomId => rooms.find(room => room.roomId === roomId));
let wrapper;
await act(async () => {
wrapper = mount(
<ForwardDialog
matrixClient={mockClient}
event={message}
permalinkCreator={new RoomPermalinkCreator(undefined, sourceRoom)}
onFinished={jest.fn()}
/>,
);
// Wait one tick for our profile data to load so the state update happens within act
await new Promise(resolve => setImmediate(resolve));
});
wrapper.update();
const wrapper: RenderResult = render(
<ForwardDialog
matrixClient={mockClient}
event={message}
permalinkCreator={new RoomPermalinkCreator(undefined, sourceRoom)}
onFinished={jest.fn()}
/>,
);
return wrapper;
};
@ -105,30 +100,29 @@ describe("ForwardDialog", () => {
});
it("shows a preview with us as the sender", async () => {
const wrapper = await mountForwardDialog();
const { container } = mountForwardDialog();
const previewBody = wrapper.find(".mx_EventTile_body");
expect(previewBody.text()).toBe("Hello world!");
expect(screen.queryByText("Hello world!")).toBeInTheDocument();
// We would just test SenderProfile for the user ID, but it's stubbed
const previewAvatar = wrapper.find(".mx_EventTile_avatar .mx_BaseAvatar_image");
expect(previewAvatar.prop("title")).toBe("@bob:example.org");
const previewAvatar = container.querySelector(".mx_EventTile_avatar .mx_BaseAvatar_image");
expect(previewAvatar?.getAttribute("title")).toBe("@bob:example.org");
});
it("filters the rooms", async () => {
const wrapper = await mountForwardDialog();
const { container } = mountForwardDialog();
expect(wrapper.find("Entry")).toHaveLength(3);
expect(container.querySelectorAll(".mx_ForwardList_entry")).toHaveLength(3);
const searchInput = wrapper.find("SearchBox input");
searchInput.instance().value = "a";
searchInput.simulate("change");
const searchInput = getByTestId(container, "searchbox-input");
act(() => userEvent.type(searchInput, "a"));
expect(wrapper.find("Entry")).toHaveLength(2);
expect(container.querySelectorAll(".mx_ForwardList_entry")).toHaveLength(3);
});
it("tracks message sending progress across multiple rooms", async () => {
const wrapper = await mountForwardDialog();
mockPlatformPeg();
const { container } = mountForwardDialog();
// Make sendEvent require manual resolution so we can see the sending state
let finishSend;
@ -141,17 +135,15 @@ describe("ForwardDialog", () => {
let firstButton;
let secondButton;
const update = () => {
wrapper.update();
firstButton = wrapper.find("AccessibleButton.mx_ForwardList_sendButton").first();
secondButton = wrapper.find("AccessibleButton.mx_ForwardList_sendButton").at(1);
[firstButton, secondButton] = container.querySelectorAll(".mx_ForwardList_sendButton");
};
update();
expect(firstButton.is(".mx_ForwardList_canSend")).toBe(true);
expect(firstButton.className).toContain("mx_ForwardList_canSend");
act(() => { firstButton.simulate("click"); });
act(() => { fireEvent.click(firstButton); });
update();
expect(firstButton.is(".mx_ForwardList_sending")).toBe(true);
expect(firstButton.className).toContain("mx_ForwardList_sending");
await act(async () => {
cancelSend();
@ -159,13 +151,13 @@ describe("ForwardDialog", () => {
await new Promise(resolve => setImmediate(resolve));
});
update();
expect(firstButton.is(".mx_ForwardList_sendFailed")).toBe(true);
expect(firstButton.className).toContain("mx_ForwardList_sendFailed");
expect(secondButton.is(".mx_ForwardList_canSend")).toBe(true);
expect(secondButton.className).toContain("mx_ForwardList_canSend");
act(() => { secondButton.simulate("click"); });
act(() => { fireEvent.click(secondButton); });
update();
expect(secondButton.is(".mx_ForwardList_sending")).toBe(true);
expect(secondButton.className).toContain("mx_ForwardList_sending");
await act(async () => {
finishSend();
@ -173,7 +165,7 @@ describe("ForwardDialog", () => {
await new Promise(resolve => setImmediate(resolve));
});
update();
expect(secondButton.is(".mx_ForwardList_sent")).toBe(true);
expect(secondButton.className).toContain("mx_ForwardList_sent");
});
it("can render replies", async () => {
@ -193,8 +185,9 @@ describe("ForwardDialog", () => {
event: true,
});
const wrapper = await mountForwardDialog(replyMessage);
expect(wrapper.find("ReplyChain")).toBeTruthy();
mountForwardDialog(replyMessage);
expect(screen.queryByText("Hi Alice!", { exact: false })).toBeInTheDocument();
});
it("disables buttons for rooms without send permissions", async () => {
@ -202,12 +195,12 @@ describe("ForwardDialog", () => {
readOnlyRoom.maySendMessage = jest.fn().mockReturnValue(false);
const rooms = [readOnlyRoom, mkStubRoom("b", "b", mockClient)];
const wrapper = await mountForwardDialog(undefined, rooms);
const { container } = mountForwardDialog(undefined, rooms);
const firstButton = wrapper.find("AccessibleButton.mx_ForwardList_sendButton").first();
expect(firstButton.prop("disabled")).toBe(true);
const secondButton = wrapper.find("AccessibleButton.mx_ForwardList_sendButton").last();
expect(secondButton.prop("disabled")).toBe(false);
const [firstButton, secondButton] = container.querySelectorAll<HTMLButtonElement>(".mx_ForwardList_sendButton");
expect(firstButton.getAttribute("aria-disabled")).toBeTruthy();
expect(secondButton.getAttribute("aria-disabled")).toBeFalsy();
});
describe('Location events', () => {
@ -229,17 +222,17 @@ describe("ForwardDialog", () => {
jest.spyOn(Date, 'now').mockRestore();
});
const sendToFirstRoom = (wrapper: ReactWrapper): void =>
const sendToFirstRoom = (container: HTMLElement): void =>
act(() => {
const sendToFirstRoomButton = wrapper.find("AccessibleButton.mx_ForwardList_sendButton").first();
sendToFirstRoomButton.simulate("click");
const sendToFirstRoomButton = container.querySelector(".mx_ForwardList_sendButton");
fireEvent.click(sendToFirstRoomButton!);
});
it('converts legacy location events to pin drop shares', async () => {
const wrapper = await mountForwardDialog(legacyLocationEvent);
const { container } = mountForwardDialog(legacyLocationEvent);
expect(wrapper.find('MLocationBody').length).toBeTruthy();
sendToFirstRoom(wrapper);
expect(container.querySelector(".mx_MLocationBody")).toBeTruthy();
sendToFirstRoom(container);
// text and description from original event are removed
// text gets new default message from event values
@ -262,10 +255,10 @@ describe("ForwardDialog", () => {
});
it('removes personal information from static self location shares', async () => {
const wrapper = await mountForwardDialog(modernLocationEvent);
const { container } = mountForwardDialog(modernLocationEvent);
expect(wrapper.find('MLocationBody').length).toBeTruthy();
sendToFirstRoom(wrapper);
expect(container.querySelector(".mx_MLocationBody")).toBeTruthy();
sendToFirstRoom(container);
const timestamp = M_TIMESTAMP.findIn<number>(modernLocationEvent.getContent());
// text and description from original event are removed
@ -302,11 +295,11 @@ describe("ForwardDialog", () => {
geo_uri: geoUri,
[M_TIMESTAMP.name]: timestamp,
};
const wrapper = await mountForwardDialog(beaconEvent);
const { container } = mountForwardDialog(beaconEvent);
expect(wrapper.find('MLocationBody').length).toBeTruthy();
expect(container.querySelector(".mx_MLocationBody")).toBeTruthy();
sendToFirstRoom(wrapper);
sendToFirstRoom(container);
expect(mockClient.sendEvent).toHaveBeenCalledWith(
roomId, EventType.RoomMessage, expectedContent,
@ -314,11 +307,11 @@ describe("ForwardDialog", () => {
});
it('forwards pin drop event', async () => {
const wrapper = await mountForwardDialog(pinDropLocationEvent);
const { container } = mountForwardDialog(pinDropLocationEvent);
expect(wrapper.find('MLocationBody').length).toBeTruthy();
expect(container.querySelector(".mx_MLocationBody")).toBeTruthy();
sendToFirstRoom(wrapper);
sendToFirstRoom(container);
expect(mockClient.sendEvent).toHaveBeenCalledWith(
roomId, pinDropLocationEvent.getType(), pinDropLocationEvent.getContent(),

View file

@ -15,9 +15,8 @@ limitations under the License.
*/
import React from 'react';
// eslint-disable-next-line deprecate/import
import { mount, ReactWrapper } from "enzyme";
import { MatrixEvent } from 'matrix-js-sdk/src/matrix';
import { render, RenderResult } from '@testing-library/react';
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
import { RoomPermalinkCreator } from "../../../../src/utils/permalinks/Permalinks";
@ -36,12 +35,13 @@ describe("MVideoBody", () => {
it('does not crash when given a portrait image', () => {
// Check for an unreliable crash caused by a fractional-sized
// image dimension being used for a CanvasImageData.
expect(makeMVideoBody(720, 1280).html()).toMatchSnapshot();
const { asFragment } = makeMVideoBody(720, 1280);
expect(asFragment()).toMatchSnapshot();
// If we get here, we did not crash.
});
});
function makeMVideoBody(w: number, h: number): ReactWrapper<any, Readonly<{}>, MVideoBody> {
function makeMVideoBody(w: number, h: number): RenderResult {
const content = {
info: {
"w": w,
@ -79,8 +79,9 @@ function makeMVideoBody(w: number, h: number): ReactWrapper<any, Readonly<{}>, M
mxcUrlToHttp: jest.fn(),
});
return mount(<MVideoBody {...defaultProps} />, {
wrappingComponent: MatrixClientContext.Provider,
wrappingComponentProps: { value: mockClient },
});
return render(
<MatrixClientContext.Provider value={mockClient}>
<MVideoBody {...defaultProps} />
</MatrixClientContext.Provider>,
);
}

View file

@ -1,3 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`MVideoBody does not crash when given a portrait image 1`] = `"<span class="mx_MVideoBody"><div class="mx_MVideoBody_container" style="max-width: 182px; max-height: 324px;"><video class="mx_MVideoBody" controls="" controlslist="nodownload" preload="none" poster="data:image/png;base64,00"></video><div style="width: 182px; height: 324px;"></div></div></span>"`;
exports[`MVideoBody does not crash when given a portrait image 1`] = `
<DocumentFragment>
<span
class="mx_MVideoBody"
>
<div
class="mx_MVideoBody_container"
style="max-width: 182px; max-height: 324px;"
>
<video
class="mx_MVideoBody"
controls=""
controlslist="nodownload"
poster="data:image/png;base64,00"
preload="none"
/>
<div
style="width: 182px; height: 324px;"
/>
</div>
</span>
</DocumentFragment>
`;

View file

@ -15,17 +15,12 @@ limitations under the License.
*/
import React from 'react';
// eslint-disable-next-line deprecate/import
import { mount } from "enzyme";
import { fireEvent, render } from '@testing-library/react';
import SearchWarning from "../../../../src/components/views/elements/SearchWarning";
import { PosthogScreenTracker } from "../../../../src/PosthogTrackers";
import SearchBar, { SearchScope } from "../../../../src/components/views/rooms/SearchBar";
import { KeyBindingAction } from "../../../../src/accessibility/KeyboardShortcuts";
let mockCurrentEvent = KeyBindingAction.Enter;
const mockWarningKind = true;
let wrapper: any = null;
const searchProps = {
onCancelClick: jest.fn(),
@ -40,95 +35,63 @@ jest.mock("../../../../src/KeyBindingsManager", () => ({
{ getAccessibilityAction: jest.fn(() => mockCurrentEvent) })),
}));
/** mock out SearchWarning component so it doesn't affect the result of our test */
jest.mock('../../../../src/components/views/elements/SearchWarning', () => ({
__esModule: true,
WarningKind: {
get Search() { // eslint-disable-line @typescript-eslint/naming-convention
return mockWarningKind;
},
},
default: jest.fn(({ children }) => (
<div>{ children }</div>
)),
}));
/** mock out PosthogTrackers component so it doesn't affect the result of our test */
jest.mock('../../../../src/PosthogTrackers', () => ({
__esModule: true,
PosthogScreenTracker: jest.fn(({ children }) => (
<div>{ children }</div>
)),
}));
describe("SearchBar", () => {
beforeEach(() => {
wrapper = mount(<SearchBar {...searchProps} />);
});
afterEach(() => {
wrapper.unmount();
searchProps.onCancelClick.mockClear();
searchProps.onSearch.mockClear();
});
it("must render child components and pass necessary props", () => {
const postHogScreenTracker = wrapper.find(PosthogScreenTracker);
const searchWarning = wrapper.find(SearchWarning);
expect(postHogScreenTracker.length).toBe(1);
expect(searchWarning.length).toBe(1);
expect(postHogScreenTracker.props().screenName).toEqual("RoomSearch");
expect(searchWarning.props().isRoomEncrypted).toEqual(searchProps.isRoomEncrypted);
expect(searchWarning.props().kind).toEqual(mockWarningKind);
});
it("must not search when input value is empty", () => {
const roomButtons = wrapper.find(".mx_SearchBar_button");
const searchButton = wrapper.find(".mx_SearchBar_searchButton");
const { container } = render(<SearchBar {...searchProps} />);
const roomButtons = container.querySelectorAll(".mx_SearchBar_button");
const searchButton = container.querySelectorAll(".mx_SearchBar_searchButton");
expect(roomButtons.length).toEqual(4);
expect(roomButtons.length).toEqual(2);
searchButton.at(0).simulate("click");
roomButtons.at(0).simulate("click");
roomButtons.at(2).simulate("click");
fireEvent.click(searchButton[0]);
fireEvent.click(roomButtons[0]);
fireEvent.click(roomButtons[1]);
expect(searchProps.onSearch).not.toHaveBeenCalled();
});
it("must trigger onSearch when value is not empty", () => {
const { container } = render(<SearchBar {...searchProps} />);
const searchValue = "abcd";
const roomButtons = wrapper.find(".mx_SearchBar_button");
const searchButton = wrapper.find(".mx_SearchBar_searchButton");
const input = wrapper.find(".mx_SearchBar_input input");
input.instance().value = searchValue;
const roomButtons = container.querySelectorAll(".mx_SearchBar_button");
const searchButton = container.querySelectorAll(".mx_SearchBar_searchButton");
const input = container.querySelector<HTMLInputElement>(".mx_SearchBar_input input");
input!.value = searchValue;
expect(roomButtons.length).toEqual(4);
expect(roomButtons.length).toEqual(2);
searchButton.at(0).simulate("click");
fireEvent.click(searchButton[0]);
expect(searchProps.onSearch).toHaveBeenCalledTimes(1);
expect(searchProps.onSearch).toHaveBeenNthCalledWith(1, searchValue, SearchScope.Room);
roomButtons.at(0).simulate("click");
fireEvent.click(roomButtons[0]);
expect(searchProps.onSearch).toHaveBeenCalledTimes(2);
expect(searchProps.onSearch).toHaveBeenNthCalledWith(2, searchValue, SearchScope.Room);
roomButtons.at(2).simulate("click");
fireEvent.click(roomButtons[1]);
expect(searchProps.onSearch).toHaveBeenCalledTimes(3);
expect(searchProps.onSearch).toHaveBeenNthCalledWith(3, searchValue, SearchScope.All);
});
it("cancel button and esc key should trigger onCancelClick", () => {
it("cancel button and esc key should trigger onCancelClick", async () => {
mockCurrentEvent = KeyBindingAction.Escape;
const cancelButton = wrapper.find(".mx_SearchBar_cancel");
const input = wrapper.find(".mx_SearchBar_input input");
input.simulate("focus");
input.simulate("keydown", { key: "ESC" });
cancelButton.at(0).simulate("click");
const { container } = render(<SearchBar {...searchProps} />);
const cancelButton = container.querySelector(".mx_SearchBar_cancel");
const input = container.querySelector(".mx_SearchBar_input input");
fireEvent.click(cancelButton!);
expect(searchProps.onCancelClick).toHaveBeenCalledTimes(1);
fireEvent.focus(input!);
fireEvent.keyDown(input!, { key: 'Escape', code: 'Escape', charCode: 27 });
expect(searchProps.onCancelClick).toHaveBeenCalledTimes(2);
});

View file

@ -15,14 +15,12 @@ limitations under the License.
*/
import * as React from "react";
// eslint-disable-next-line deprecate/import
import { mount } from "enzyme";
import { SearchResult } from "matrix-js-sdk/src/models/search-result";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { render } from "@testing-library/react";
import { createTestClient } from "../../../test-utils";
import EventTile from "../../../../src/components/views/rooms/EventTile";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import SearchResultTile from "../../../../src/components/views/rooms/SearchResultTile";
@ -32,7 +30,7 @@ describe("SearchResultTile", () => {
});
it("Sets up appropriate callEventGrouper for m.call. events", () => {
const wrapper = mount(
const { container } = render(
<SearchResultTile
searchResult={SearchResult.fromJson({
rank: 0.00424866,
@ -77,11 +75,9 @@ describe("SearchResultTile", () => {
/>,
);
const tiles = wrapper.find(EventTile);
const tiles = container.querySelectorAll<HTMLElement>(".mx_EventTile");
expect(tiles.length).toEqual(2);
expect(tiles.at(0).prop("mxEvent").getId()).toBe("$1:server");
// @ts-ignore accessing private property
expect(tiles.at(0).prop("callEventGrouper").events.size).toBe(2);
expect(tiles.at(1).prop("mxEvent").getId()).toBe("$144429830826TWwbB:localhost");
expect(tiles[0].dataset.eventId).toBe("$1:server");
expect(tiles[1].dataset.eventId).toBe("$144429830826TWwbB:localhost");
});
});

View file

@ -15,8 +15,7 @@ limitations under the License.
*/
import React from 'react';
// eslint-disable-next-line deprecate/import
import { mount } from "enzyme";
import { render } from '@testing-library/react';
import * as TestUtils from "../../../test-utils";
import FontScalingPanel from '../../../../src/components/views/settings/FontScalingPanel';
@ -34,9 +33,9 @@ jest.mock(
describe('FontScalingPanel', () => {
it('renders the font scaling UI', () => {
TestUtils.stubClient();
const wrapper = mount(
const { asFragment } = render(
<FontScalingPanel />,
);
expect(wrapper).toMatchSnapshot();
expect(asFragment()).toMatchSnapshot();
});
});

View file

@ -15,8 +15,7 @@ limitations under the License.
*/
import React from 'react';
// eslint-disable-next-line deprecate/import
import { mount } from "enzyme";
import { render } from '@testing-library/react';
import * as TestUtils from "../../../test-utils";
import ThemeChoicePanel from '../../../../src/components/views/settings/ThemeChoicePanel';
@ -34,9 +33,9 @@ jest.mock(
describe('ThemeChoicePanel', () => {
it('renders the theme choice UI', () => {
TestUtils.stubClient();
const wrapper = mount(
const { asFragment } = render(
<ThemeChoicePanel />,
);
expect(wrapper).toMatchSnapshot();
expect(asFragment()).toMatchSnapshot();
});
});

View file

@ -15,8 +15,7 @@ limitations under the License.
*/
import React from 'react';
// eslint-disable-next-line deprecate/import
import { mount } from 'enzyme';
import { render } from '@testing-library/react';
import SettingsStore from '../../../../src/settings/SettingsStore';
import UiFeatureSettingWrapper from '../../../../src/components/views/settings/UiFeatureSettingWrapper';
@ -29,29 +28,29 @@ describe('<UiFeatureSettingWrapper>', () => {
uiFeature: UIFeature.Feedback,
children: <div>test</div>,
};
const getComponent = (props = {}) => mount(<UiFeatureSettingWrapper {...defaultProps} {...props} />);
const getComponent = (props = {}) => render(<UiFeatureSettingWrapper {...defaultProps} {...props} />);
beforeEach(() => {
(SettingsStore.getValue as jest.Mock).mockClear().mockReturnValue(true);
});
it('renders children when setting is truthy', () => {
const component = getComponent();
const { asFragment } = getComponent();
expect(component).toMatchSnapshot();
expect(asFragment()).toMatchSnapshot();
expect(SettingsStore.getValue).toHaveBeenCalledWith(defaultProps.uiFeature);
});
it('returns null when setting is truthy but children are undefined', () => {
const component = getComponent({ children: undefined });
const { asFragment } = getComponent({ children: undefined });
expect(component.html()).toBeNull();
expect(asFragment()).toMatchSnapshot();
});
it('returns null when setting is falsy', () => {
(SettingsStore.getValue as jest.Mock).mockReturnValue(false);
const component = getComponent();
const { asFragment } = getComponent();
expect(component.html()).toBeNull();
expect(asFragment()).toMatchSnapshot();
});
});

View file

@ -1,313 +1,186 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`FontScalingPanel renders the font scaling UI 1`] = `
<FontScalingPanel>
<DocumentFragment>
<div
className="mx_SettingsTab_section mx_FontScalingPanel"
class="mx_SettingsTab_section mx_FontScalingPanel"
>
<span
className="mx_SettingsTab_subheading"
class="mx_SettingsTab_subheading"
>
Font size
</span>
<EventTilePreview
avatarUrl={null}
className="mx_FontScalingPanel_preview"
displayName={null}
layout="group"
message="Hey you. You're the best!"
userId={null}
>
<div
className="mx_FontScalingPanel_preview mx_EventTilePreview_loader"
>
<Spinner
h={32}
w={32}
>
<div
className="mx_Spinner"
>
<div
aria-label="Loading..."
className="mx_Spinner_icon"
data-testid="spinner"
role="progressbar"
style={
{
"height": 32,
"width": 32,
}
}
/>
</div>
</Spinner>
</div>
</EventTilePreview>
<div
className="mx_FontScalingPanel_fontSlider"
class="mx_FontScalingPanel_preview mx_EventTilePreview_loader"
>
<div
className="mx_FontScalingPanel_fontSlider_smallText"
class="mx_Spinner"
>
<div
aria-label="Loading..."
class="mx_Spinner_icon"
data-testid="spinner"
role="progressbar"
style="width: 32px; height: 32px;"
/>
</div>
</div>
<div
class="mx_FontScalingPanel_fontSlider"
>
<div
class="mx_FontScalingPanel_fontSlider_smallText"
>
Aa
</div>
<Slider
disabled={false}
displayFunc={[Function]}
onSelectionChange={[Function]}
value={15}
values={
[
13,
14,
15,
16,
18,
]
}
<div
class="mx_Slider"
>
<div
className="mx_Slider"
>
<div>
<div>
<div
class="mx_Slider_bar"
>
<hr />
<div
className="mx_Slider_bar"
class="mx_Slider_selection"
>
<hr
onClick={[Function]}
/>
<div
className="mx_Slider_selection"
class="mx_Slider_selectionDot"
style="left: calc(-1.195em + 50%);"
>
<div
className="mx_Slider_selectionDot"
style={
{
"left": "calc(-1.195em + 50%)",
}
}
class="mx_Slider_selectionText"
>
<div
className="mx_Slider_selectionText"
>
15
</div>
15
</div>
<hr
style={
{
"width": "50%",
}
}
/>
</div>
</div>
<div
className="mx_Slider_dotContainer"
>
<Dot
active={true}
disabled={false}
key="13"
label=""
onClick={[Function]}
>
<span
className="mx_Slider_dotValue"
onClick={[Function]}
>
<div
className="mx_Slider_dot mx_Slider_dotActive"
/>
<div
className="mx_Slider_labelContainer"
>
<div
className="mx_Slider_label"
/>
</div>
</span>
</Dot>
<Dot
active={true}
disabled={false}
key="14"
label=""
onClick={[Function]}
>
<span
className="mx_Slider_dotValue"
onClick={[Function]}
>
<div
className="mx_Slider_dot mx_Slider_dotActive"
/>
<div
className="mx_Slider_labelContainer"
>
<div
className="mx_Slider_label"
/>
</div>
</span>
</Dot>
<Dot
active={true}
disabled={false}
key="15"
label=""
onClick={[Function]}
>
<span
className="mx_Slider_dotValue"
onClick={[Function]}
>
<div
className="mx_Slider_dot mx_Slider_dotActive"
/>
<div
className="mx_Slider_labelContainer"
>
<div
className="mx_Slider_label"
/>
</div>
</span>
</Dot>
<Dot
active={false}
disabled={false}
key="16"
label=""
onClick={[Function]}
>
<span
className="mx_Slider_dotValue"
onClick={[Function]}
>
<div
className="mx_Slider_dot"
/>
<div
className="mx_Slider_labelContainer"
>
<div
className="mx_Slider_label"
/>
</div>
</span>
</Dot>
<Dot
active={false}
disabled={false}
key="18"
label=""
onClick={[Function]}
>
<span
className="mx_Slider_dotValue"
onClick={[Function]}
>
<div
className="mx_Slider_dot"
/>
<div
className="mx_Slider_labelContainer"
>
<div
className="mx_Slider_label"
/>
</div>
</span>
</Dot>
<hr
style="width: 50%;"
/>
</div>
</div>
<div
class="mx_Slider_dotContainer"
>
<span
class="mx_Slider_dotValue"
>
<div
class="mx_Slider_dot mx_Slider_dotActive"
/>
<div
class="mx_Slider_labelContainer"
>
<div
class="mx_Slider_label"
/>
</div>
</span>
<span
class="mx_Slider_dotValue"
>
<div
class="mx_Slider_dot mx_Slider_dotActive"
/>
<div
class="mx_Slider_labelContainer"
>
<div
class="mx_Slider_label"
/>
</div>
</span>
<span
class="mx_Slider_dotValue"
>
<div
class="mx_Slider_dot mx_Slider_dotActive"
/>
<div
class="mx_Slider_labelContainer"
>
<div
class="mx_Slider_label"
/>
</div>
</span>
<span
class="mx_Slider_dotValue"
>
<div
class="mx_Slider_dot"
/>
<div
class="mx_Slider_labelContainer"
>
<div
class="mx_Slider_label"
/>
</div>
</span>
<span
class="mx_Slider_dotValue"
>
<div
class="mx_Slider_dot"
/>
<div
class="mx_Slider_labelContainer"
>
<div
class="mx_Slider_label"
/>
</div>
</span>
</div>
</div>
</Slider>
</div>
<div
className="mx_FontScalingPanel_fontSlider_largeText"
class="mx_FontScalingPanel_fontSlider_largeText"
>
Aa
</div>
</div>
<SettingsFlag
level="account"
name="useCustomFontSize"
onChange={[Function]}
useCheckbox={true}
<span
class="mx_Checkbox mx_Checkbox_hasKind mx_Checkbox_kind_solid"
>
<StyledCheckbox
checked={false}
className=""
disabled={false}
onChange={[Function]}
<input
id="checkbox_abdefghi"
type="checkbox"
/>
<label
for="checkbox_abdefghi"
>
<span
className="mx_Checkbox mx_Checkbox_hasKind mx_Checkbox_kind_solid"
<div
class="mx_Checkbox_background"
>
<input
checked={false}
disabled={false}
id="checkbox_abdefghi"
onChange={[Function]}
type="checkbox"
<div
class="mx_Checkbox_checkmark"
/>
<label
htmlFor="checkbox_abdefghi"
>
<div
className="mx_Checkbox_background"
>
<div
className="mx_Checkbox_checkmark"
/>
</div>
<div>
Use custom size
</div>
</label>
</span>
</StyledCheckbox>
</SettingsFlag>
<Field
autoComplete="off"
className="mx_FontScalingPanel_customFontSizeField"
disabled={true}
element="input"
id="font_size_field"
label="Font size"
onChange={[Function]}
onValidate={[Function]}
placeholder="15"
type="number"
validateOnBlur={true}
validateOnChange={true}
validateOnFocus={true}
value="15"
</div>
<div>
Use custom size
</div>
</label>
</span>
<div
class="mx_Field mx_Field_input mx_FontScalingPanel_customFontSizeField"
>
<div
className="mx_Field mx_Field_input mx_FontScalingPanel_customFontSizeField"
<input
autocomplete="off"
disabled=""
id="font_size_field"
label="Font size"
placeholder="15"
type="number"
value="15"
/>
<label
for="font_size_field"
>
<input
autoComplete="off"
disabled={true}
id="font_size_field"
label="Font size"
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
placeholder="15"
type="number"
value="15"
/>
<label
htmlFor="font_size_field"
>
Font size
</label>
</div>
</Field>
Font size
</label>
</div>
</div>
</FontScalingPanel>
</DocumentFragment>
`;

View file

@ -1,113 +1,63 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ThemeChoicePanel renders the theme choice UI 1`] = `
<ThemeChoicePanel>
<DocumentFragment>
<div
className="mx_SettingsTab_section mx_ThemeChoicePanel"
class="mx_SettingsTab_section mx_ThemeChoicePanel"
>
<span
className="mx_SettingsTab_subheading"
class="mx_SettingsTab_subheading"
>
Theme
</span>
<div
className="mx_ThemeSelectors"
class="mx_ThemeSelectors"
>
<StyledRadioGroup
definitions={
[
{
"className": "mx_ThemeSelector_light",
"disabled": true,
"label": "Light",
"value": "light",
},
{
"className": "mx_ThemeSelector_dark",
"disabled": true,
"label": "Dark",
"value": "dark",
},
]
}
name="theme"
onChange={[Function]}
outlined={true}
<label
class="mx_StyledRadioButton mx_ThemeSelector_light mx_StyledRadioButton_disabled mx_StyledRadioButton_outlined"
>
<StyledRadioButton
checked={false}
childrenInLabel={true}
className="mx_ThemeSelector_light"
disabled={true}
<input
disabled=""
id="theme-light"
name="theme"
onChange={[Function]}
outlined={true}
type="radio"
value="light"
/>
<div>
<div />
</div>
<div
class="mx_StyledRadioButton_content"
>
<label
className="mx_StyledRadioButton mx_ThemeSelector_light mx_StyledRadioButton_disabled mx_StyledRadioButton_outlined"
>
<input
checked={false}
disabled={true}
id="theme-light"
name="theme"
onChange={[Function]}
type="radio"
value="light"
/>
<div>
<div />
</div>
<div
className="mx_StyledRadioButton_content"
>
Light
</div>
<div
className="mx_StyledRadioButton_spacer"
/>
</label>
</StyledRadioButton>
<StyledRadioButton
checked={false}
childrenInLabel={true}
className="mx_ThemeSelector_dark"
disabled={true}
Light
</div>
<div
class="mx_StyledRadioButton_spacer"
/>
</label>
<label
class="mx_StyledRadioButton mx_ThemeSelector_dark mx_StyledRadioButton_disabled mx_StyledRadioButton_outlined"
>
<input
disabled=""
id="theme-dark"
name="theme"
onChange={[Function]}
outlined={true}
type="radio"
value="dark"
/>
<div>
<div />
</div>
<div
class="mx_StyledRadioButton_content"
>
<label
className="mx_StyledRadioButton mx_ThemeSelector_dark mx_StyledRadioButton_disabled mx_StyledRadioButton_outlined"
>
<input
checked={false}
disabled={true}
id="theme-dark"
name="theme"
onChange={[Function]}
type="radio"
value="dark"
/>
<div>
<div />
</div>
<div
className="mx_StyledRadioButton_content"
>
Dark
</div>
<div
className="mx_StyledRadioButton_spacer"
/>
</label>
</StyledRadioButton>
</StyledRadioGroup>
Dark
</div>
<div
class="mx_StyledRadioButton_spacer"
/>
</label>
</div>
</div>
</ThemeChoicePanel>
</DocumentFragment>
`;

View file

@ -1,11 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<UiFeatureSettingWrapper> renders children when setting is truthy 1`] = `
<UiFeatureSettingWrapper
uiFeature="UIFeature.feedback"
>
<DocumentFragment>
<div>
test
</div>
</UiFeatureSettingWrapper>
</DocumentFragment>
`;
exports[`<UiFeatureSettingWrapper> returns null when setting is falsy 1`] = `<DocumentFragment />`;
exports[`<UiFeatureSettingWrapper> returns null when setting is truthy but children are undefined 1`] = `<DocumentFragment />`;