Automatically focus the WYSIWYG composer when you enter a room (#9412)

Automatically focus the WYSIWYG composer when you enter a room
This commit is contained in:
Andy Balaam 2022-10-17 12:48:47 +01:00 committed by GitHub
parent 13e9e14eaa
commit e38c9e036c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 144 additions and 12 deletions

View file

@ -14,15 +14,18 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import "@testing-library/jest-dom";
import React from "react";
import { act, render, screen } from "@testing-library/react";
import { act, render, screen, waitFor } from "@testing-library/react";
import { IRoomState } from "../../../../../src/components/structures/RoomView";
import RoomContext, { TimelineRenderingType } from "../../../../../src/contexts/RoomContext";
import { Layout } from "../../../../../src/settings/enums/Layout";
import { createTestClient, mkEvent, mkStubRoom } from "../../../../test-utils";
import MatrixClientContext from "../../../../../src/contexts/MatrixClientContext";
import RoomContext, { TimelineRenderingType } from "../../../../../src/contexts/RoomContext";
import defaultDispatcher from "../../../../../src/dispatcher/dispatcher";
import { Action } from "../../../../../src/dispatcher/actions";
import { IRoomState } from "../../../../../src/components/structures/RoomView";
import { Layout } from "../../../../../src/settings/enums/Layout";
import { WysiwygComposer } from "../../../../../src/components/views/rooms/wysiwyg_composer/WysiwygComposer";
import { createTestClient, mkEvent, mkStubRoom } from "../../../../test-utils";
// The wysiwyg fetch wasm bytes and a specific workaround is needed to make it works in a node (jest) environnement
// See https://github.com/matrix-org/matrix-wysiwyg/blob/main/platforms/web/test.setup.ts
@ -92,7 +95,7 @@ describe('WysiwygComposer', () => {
};
let sendMessage: () => void;
const customRender = (onChange = (content: string) => void 0, disabled = false) => {
const customRender = (onChange = (_content: string) => void 0, disabled = false) => {
return render(
<MatrixClientContext.Provider value={mockClient}>
<RoomContext.Provider value={defaultRoomContext}>
@ -140,5 +143,58 @@ describe('WysiwygComposer', () => {
expect(mockClient.sendMessage).toBeCalledWith('myfakeroom', null, expectedContent);
expect(screen.getByRole('textbox')).toHaveFocus();
});
it('Should focus when receiving an Action.FocusSendMessageComposer action', async () => {
// Given we don't have focus
customRender(() => {}, false);
expect(screen.getByRole('textbox')).not.toHaveFocus();
// When we send the right action
defaultDispatcher.dispatch({
action: Action.FocusSendMessageComposer,
context: null,
});
// Then the component gets the focus
await waitFor(() => expect(screen.getByRole('textbox')).toHaveFocus());
});
it('Should focus when receiving a reply_to_event action', async () => {
// Given we don't have focus
customRender(() => {}, false);
expect(screen.getByRole('textbox')).not.toHaveFocus();
// When we send the right action
defaultDispatcher.dispatch({
action: "reply_to_event",
context: null,
});
// Then the component gets the focus
await waitFor(() => expect(screen.getByRole('textbox')).toHaveFocus());
});
it('Should not focus when disabled', async () => {
// Given we don't have focus and we are disabled
customRender(() => {}, true);
expect(screen.getByRole('textbox')).not.toHaveFocus();
// When we send an action that would cause us to get focus
defaultDispatcher.dispatch({
action: Action.FocusSendMessageComposer,
context: null,
});
// (Send a second event to exercise the clearTimeout logic)
defaultDispatcher.dispatch({
action: Action.FocusSendMessageComposer,
context: null,
});
// Wait for event dispatch to happen
await new Promise((r) => setTimeout(r, 200));
// Then we don't get it because we are disabled
expect(screen.getByRole('textbox')).not.toHaveFocus();
});
});