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

Commit e9d7232

Browse files
GermainAlun Turner
andauthored
Use CopyableText in devtools (#9993)
Co-authored-by: Alun Turner <[email protected]>
1 parent c71dceb commit e9d7232

File tree

3 files changed

+310
-5
lines changed

3 files changed

+310
-5
lines changed

src/components/views/dialogs/DevtoolsDialog.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
Copyright 2022 Michael Telatynski <[email protected]>
3-
Copyright 2018-2021 The Matrix.org Foundation C.I.C.
3+
Copyright 2018-2023 The Matrix.org Foundation C.I.C.
44
55
Licensed under the Apache License, Version 2.0 (the "License");
66
you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@ import SettingsFlag from "../elements/SettingsFlag";
3232
import { SettingLevel } from "../../../settings/SettingLevel";
3333
import ServerInfo from "./devtools/ServerInfo";
3434
import { Features } from "../../../settings/Settings";
35+
import CopyableText from "../elements/CopyableText";
3536

3637
enum Category {
3738
Room,
@@ -119,11 +120,15 @@ const DevtoolsDialog: React.FC<IProps> = ({ roomId, onFinished }) => {
119120
{(cli) => (
120121
<>
121122
<div className="mx_DevTools_label_left">{label}</div>
122-
<div className="mx_DevTools_label_right">{_t("Room ID: %(roomId)s", { roomId })}</div>
123+
<CopyableText className="mx_DevTools_label_right" getTextToCopy={() => roomId} border={false}>
124+
{_t("Room ID: %(roomId)s", { roomId })}
125+
</CopyableText>
123126
<div className="mx_DevTools_label_bottom" />
124-
<DevtoolsContext.Provider value={{ room: cli.getRoom(roomId) }}>
125-
{body}
126-
</DevtoolsContext.Provider>
127+
{cli.getRoom(roomId) && (
128+
<DevtoolsContext.Provider value={{ room: cli.getRoom(roomId)! }}>
129+
{body}
130+
</DevtoolsContext.Provider>
131+
)}
127132
</>
128133
)}
129134
</MatrixClientContext.Consumer>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
Copyright 2023 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import React from "react";
18+
import { getByLabelText, render } from "@testing-library/react";
19+
import { Room } from "matrix-js-sdk/src/models/room";
20+
import { MatrixClient } from "matrix-js-sdk/src/client";
21+
import userEvent from "@testing-library/user-event";
22+
23+
import { stubClient } from "../../../test-utils";
24+
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
25+
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
26+
import DevtoolsDialog from "../../../../src/components/views/dialogs/DevtoolsDialog";
27+
28+
describe("DevtoolsDialog", () => {
29+
let cli: MatrixClient;
30+
let room: Room;
31+
32+
function getComponent(roomId: string, onFinished = () => true) {
33+
return render(
34+
<MatrixClientContext.Provider value={cli}>
35+
<DevtoolsDialog roomId={roomId} onFinished={onFinished} />
36+
</MatrixClientContext.Provider>,
37+
);
38+
}
39+
40+
beforeEach(() => {
41+
stubClient();
42+
cli = MatrixClientPeg.get();
43+
room = new Room("!id", cli, "@alice:matrix.org");
44+
45+
jest.spyOn(cli, "getRoom").mockReturnValue(room);
46+
});
47+
48+
afterAll(() => {
49+
jest.restoreAllMocks();
50+
});
51+
52+
it("renders the devtools dialog", () => {
53+
const { asFragment } = getComponent(room.roomId);
54+
expect(asFragment()).toMatchSnapshot();
55+
});
56+
57+
it("copies the roomid", async () => {
58+
const user = userEvent.setup();
59+
jest.spyOn(navigator.clipboard, "writeText");
60+
61+
const { container } = getComponent(room.roomId);
62+
63+
const copyBtn = getByLabelText(container, "Copy");
64+
await user.click(copyBtn);
65+
const copiedBtn = getByLabelText(container, "Copied!");
66+
67+
expect(copiedBtn).toBeInTheDocument();
68+
expect(navigator.clipboard.writeText).toHaveBeenCalled();
69+
expect(navigator.clipboard.readText()).resolves.toBe(room.roomId);
70+
});
71+
});
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`DevtoolsDialog renders the devtools dialog 1`] = `
4+
<DocumentFragment>
5+
<div
6+
data-focus-guard="true"
7+
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
8+
tabindex="0"
9+
/>
10+
<div
11+
aria-labelledby="mx_BaseDialog_title"
12+
class="mx_QuestionDialog mx_Dialog_fixedWidth"
13+
data-focus-lock-disabled="false"
14+
role="dialog"
15+
>
16+
<div
17+
class="mx_Dialog_header mx_Dialog_headerWithCancel"
18+
>
19+
<h2
20+
class="mx_Heading_h2 mx_Dialog_title"
21+
id="mx_BaseDialog_title"
22+
>
23+
Developer Tools
24+
</h2>
25+
<div
26+
aria-label="Close dialog"
27+
class="mx_AccessibleButton mx_Dialog_cancelButton"
28+
role="button"
29+
tabindex="0"
30+
/>
31+
</div>
32+
<div
33+
class="mx_DevTools_label_left"
34+
>
35+
Toolbox
36+
</div>
37+
<div
38+
class="mx_CopyableText mx_DevTools_label_right"
39+
>
40+
Room ID: !id
41+
<div
42+
aria-label="Copy"
43+
class="mx_AccessibleButton mx_CopyableText_copyButton"
44+
role="button"
45+
tabindex="0"
46+
/>
47+
</div>
48+
<div
49+
class="mx_DevTools_label_bottom"
50+
/>
51+
<div
52+
class="mx_DevTools_content"
53+
>
54+
<div>
55+
<h3>
56+
Room
57+
</h3>
58+
<button
59+
class="mx_DevTools_button"
60+
>
61+
Send custom timeline event
62+
</button>
63+
<button
64+
class="mx_DevTools_button"
65+
>
66+
Explore room state
67+
</button>
68+
<button
69+
class="mx_DevTools_button"
70+
>
71+
Explore room account data
72+
</button>
73+
<button
74+
class="mx_DevTools_button"
75+
>
76+
View servers in room
77+
</button>
78+
<button
79+
class="mx_DevTools_button"
80+
>
81+
Verification explorer
82+
</button>
83+
<button
84+
class="mx_DevTools_button"
85+
>
86+
Active Widgets
87+
</button>
88+
</div>
89+
<div>
90+
<h3>
91+
Other
92+
</h3>
93+
<button
94+
class="mx_DevTools_button"
95+
>
96+
Explore account data
97+
</button>
98+
<button
99+
class="mx_DevTools_button"
100+
>
101+
Settings explorer
102+
</button>
103+
<button
104+
class="mx_DevTools_button"
105+
>
106+
Server info
107+
</button>
108+
</div>
109+
<div>
110+
<h3>
111+
Options
112+
</h3>
113+
<div
114+
class="mx_SettingsFlag"
115+
>
116+
<label
117+
class="mx_SettingsFlag_label"
118+
>
119+
<span
120+
class="mx_SettingsFlag_labelText"
121+
>
122+
Developer mode
123+
</span>
124+
</label>
125+
<div
126+
aria-checked="false"
127+
aria-disabled="false"
128+
aria-label="Developer mode"
129+
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_enabled"
130+
role="switch"
131+
tabindex="0"
132+
>
133+
<div
134+
class="mx_ToggleSwitch_ball"
135+
/>
136+
</div>
137+
</div>
138+
<div
139+
class="mx_SettingsFlag"
140+
>
141+
<label
142+
class="mx_SettingsFlag_label"
143+
>
144+
<span
145+
class="mx_SettingsFlag_labelText"
146+
>
147+
Show hidden events in timeline
148+
</span>
149+
</label>
150+
<div
151+
aria-checked="false"
152+
aria-disabled="false"
153+
aria-label="Show hidden events in timeline"
154+
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_enabled"
155+
role="switch"
156+
tabindex="0"
157+
>
158+
<div
159+
class="mx_ToggleSwitch_ball"
160+
/>
161+
</div>
162+
</div>
163+
<div
164+
class="mx_SettingsFlag"
165+
>
166+
<label
167+
class="mx_SettingsFlag_label"
168+
>
169+
<span
170+
class="mx_SettingsFlag_labelText"
171+
>
172+
Enable widget screenshots on supported widgets
173+
</span>
174+
</label>
175+
<div
176+
aria-checked="false"
177+
aria-disabled="false"
178+
aria-label="Enable widget screenshots on supported widgets"
179+
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_enabled"
180+
role="switch"
181+
tabindex="0"
182+
>
183+
<div
184+
class="mx_ToggleSwitch_ball"
185+
/>
186+
</div>
187+
</div>
188+
<div
189+
class="mx_SettingsFlag"
190+
>
191+
<label
192+
class="mx_SettingsFlag_label"
193+
>
194+
<span
195+
class="mx_SettingsFlag_labelText"
196+
>
197+
Force 15s voice broadcast chunk length
198+
</span>
199+
</label>
200+
<div
201+
aria-checked="false"
202+
aria-disabled="false"
203+
aria-label="Force 15s voice broadcast chunk length"
204+
class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_enabled"
205+
role="switch"
206+
tabindex="0"
207+
>
208+
<div
209+
class="mx_ToggleSwitch_ball"
210+
/>
211+
</div>
212+
</div>
213+
</div>
214+
</div>
215+
<div
216+
class="mx_Dialog_buttons"
217+
>
218+
<button>
219+
Back
220+
</button>
221+
</div>
222+
</div>
223+
<div
224+
data-focus-guard="true"
225+
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
226+
tabindex="0"
227+
/>
228+
</DocumentFragment>
229+
`;

0 commit comments

Comments
 (0)