Skip to content

Commit 53a648f

Browse files
feat(learn): Added keyboard shortcut(ctrl+enter) to check your answer button (freeCodeCamp#61333)
Co-authored-by: Huyen Nguyen <25715018+huyenltnguyen@users.noreply.github.com>
1 parent 806b738 commit 53a648f

2 files changed

Lines changed: 90 additions & 13 deletions

File tree

client/src/templates/Challenges/generic/show.tsx

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Container, Col, Row, Button, Spacer } from '@freecodecamp/ui';
77
import { isEqual } from 'lodash';
88
import store from 'store';
99
import { YouTubeEvent } from 'react-youtube';
10+
import { ObserveKeys } from 'react-hotkeys';
1011

1112
// Local Utilities
1213
import LearnLayout from '../../../components/layouts/learn';
@@ -259,21 +260,25 @@ const ShowGeneric = ({
259260
)}
260261

261262
{assignments.length > 0 && (
262-
<Assignments
263-
assignments={assignments}
264-
allAssignmentsCompleted={allAssignmentsCompleted}
265-
handleAssignmentChange={handleAssignmentChange}
266-
/>
263+
<ObserveKeys only={['ctrl', 'cmd', 'enter']}>
264+
<Assignments
265+
assignments={assignments}
266+
allAssignmentsCompleted={allAssignmentsCompleted}
267+
handleAssignmentChange={handleAssignmentChange}
268+
/>
269+
</ObserveKeys>
267270
)}
268271

269272
{questions.length > 0 && (
270-
<MultipleChoiceQuestions
271-
questions={questions}
272-
selectedOptions={selectedMcqOptions}
273-
handleOptionChange={handleMcqOptionChange}
274-
submittedMcqAnswers={submittedMcqAnswers}
275-
showFeedback={showFeedback}
276-
/>
273+
<ObserveKeys only={['ctrl', 'cmd', 'enter']}>
274+
<MultipleChoiceQuestions
275+
questions={questions}
276+
selectedOptions={selectedMcqOptions}
277+
handleOptionChange={handleMcqOptionChange}
278+
submittedMcqAnswers={submittedMcqAnswers}
279+
showFeedback={showFeedback}
280+
/>
281+
</ObserveKeys>
277282
)}
278283

279284
{explanation ? (

e2e/hotkeys.spec.ts

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ const links = {
2121
video1:
2222
'/learn/python-for-everybody/python-for-everybody/introduction-why-program',
2323
video2:
24-
'/learn/python-for-everybody/python-for-everybody/introduction-hardware-architecture'
24+
'/learn/python-for-everybody/python-for-everybody/introduction-hardware-architecture',
25+
multipleChoiceQuestion:
26+
'/learn/a2-english-for-developers/learn-greetings-in-your-first-day-at-the-office/task-7',
27+
assignment:
28+
'/learn/full-stack-developer/review-semantic-html/review-semantic-html'
2529
};
2630

2731
const titles = {
@@ -143,3 +147,71 @@ test('User can use shortcuts to navigate between video-based challenges', async
143147
await page.keyboard.press('p');
144148
await page.waitForURL(links.video1);
145149
});
150+
151+
test('User can use Ctrl+Enter to submit their answer in a multiple-choice question challenge', async ({
152+
page
153+
}) => {
154+
await page.goto(links.multipleChoiceQuestion);
155+
156+
// Wait for page load
157+
await expect(page.getByRole('heading', { name: 'Task 7' })).toBeVisible();
158+
159+
await page.keyboard.press('Control+Enter');
160+
161+
await expect(
162+
page.getByText('You have unanswered questions and/or incorrect answers.')
163+
).toBeVisible();
164+
});
165+
166+
test('User can use Cmd+Enter to submit their answer in a multiple-choice question challenge', async ({
167+
page
168+
}) => {
169+
await page.goto(links.multipleChoiceQuestion);
170+
171+
// Wait for page load
172+
await expect(page.getByRole('heading', { name: 'Task 7' })).toBeVisible();
173+
174+
await page.keyboard.press('Meta+Enter');
175+
176+
await expect(
177+
page.getByText('You have unanswered questions and/or incorrect answers.')
178+
).toBeVisible();
179+
});
180+
181+
test('User can use Ctrl+Enter to submit their answer in an assignment-type challenge', async ({
182+
page
183+
}) => {
184+
await page.goto(links.assignment);
185+
186+
// Wait for page load
187+
await expect(
188+
page.getByRole('heading', { name: 'Semantic HTML Review' })
189+
).toBeVisible();
190+
191+
// Check the assignment checkbox
192+
await page.getByRole('checkbox').check();
193+
194+
await page.keyboard.press('Control+Enter');
195+
196+
// Completion modal shows up
197+
await expect(page.getByRole('dialog')).toBeVisible();
198+
});
199+
200+
test('User can use Cmd+Enter to submit their answer in an assignment-type challenge', async ({
201+
page
202+
}) => {
203+
await page.goto(links.assignment);
204+
205+
// Wait for page load
206+
await expect(
207+
page.getByRole('heading', { name: 'Semantic HTML Review' })
208+
).toBeVisible();
209+
210+
// Check the assignment checkbox
211+
await page.getByRole('checkbox').check();
212+
213+
await page.keyboard.press('Meta+Enter');
214+
215+
// Completion modal shows up
216+
await expect(page.getByRole('dialog')).toBeVisible();
217+
});

0 commit comments

Comments
 (0)