mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2025-12-30 03:03:06 -05:00
feat: convert hotkeys tests to Playwright (#54938)
Co-authored-by: Huyen Nguyen <25715018+huyenltnguyen@users.noreply.github.com>
This commit is contained in:
@@ -1,107 +0,0 @@
|
||||
import { selectors } from '../../../support/selectors';
|
||||
|
||||
const hotKeySelectors = {
|
||||
instructions: '.challenge-instructions',
|
||||
instructionsPanel: '.instructions-panel',
|
||||
editorContainer: '.monaco-editor'
|
||||
};
|
||||
|
||||
const links = {
|
||||
classic1:
|
||||
'/learn/responsive-web-design/basic-html-and-html5/say-hello-to-html-elements',
|
||||
classic2:
|
||||
'/learn/responsive-web-design/basic-html-and-html5/headline-with-the-h2-element',
|
||||
frontEnd1:
|
||||
'/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-random-quote-machine',
|
||||
frontEnd2:
|
||||
'/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-markdown-previewer',
|
||||
backEnd1:
|
||||
'/learn/back-end-development-and-apis/back-end-development-and-apis-projects/timestamp-microservice',
|
||||
backEnd2:
|
||||
'learn/back-end-development-and-apis/back-end-development-and-apis-projects/request-header-parser-microservice',
|
||||
video1:
|
||||
'/learn/scientific-computing-with-python/python-for-everybody/introduction-why-program',
|
||||
video2:
|
||||
'learn/scientific-computing-with-python/python-for-everybody/introduction-hardware-architecture'
|
||||
};
|
||||
|
||||
// It's possible for the location to change before the new page has loaded, so
|
||||
// we wait for these titles to be present:
|
||||
const titles = {
|
||||
classic2: 'Headline with the h2 Element',
|
||||
frontEnd2: 'Build a Markdown Previewer',
|
||||
backEnd2: 'Request Header Parser Microservice',
|
||||
video2: 'Introduction: Hardware Architecture'
|
||||
};
|
||||
|
||||
describe('The hotkeys should work correctly', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.visit('/settings');
|
||||
// enable shortcuts
|
||||
cy.get('form[data-testid="fcc-enable-shortcuts-setting"]').within(() => {
|
||||
cy.contains('On').click();
|
||||
});
|
||||
});
|
||||
it('should be possible to navigate to the next challenge/projects and previous', () => {
|
||||
cy.visit(links.classic1);
|
||||
cy.focused().type('{esc}');
|
||||
cy.focused().type('n');
|
||||
cy.url().should('include', links.classic2);
|
||||
cy.contains(titles.classic2);
|
||||
cy.focused().type('p');
|
||||
cy.url().should('include', links.classic1);
|
||||
cy.visit(links.frontEnd1);
|
||||
cy.focused().type('{esc}').type('n');
|
||||
cy.url().should('include', links.frontEnd2);
|
||||
cy.contains(titles.frontEnd2);
|
||||
cy.focused().type('p');
|
||||
cy.url().should('include', links.frontEnd1);
|
||||
});
|
||||
|
||||
it('should be possible to navigate to the next (and previous) video', () => {
|
||||
cy.visit(links.video1);
|
||||
cy.focused().type('{esc}').type('n');
|
||||
cy.url().should('include', links.video2);
|
||||
cy.contains(titles.video2);
|
||||
cy.focused().type('p');
|
||||
cy.url().should('include', links.video1);
|
||||
});
|
||||
|
||||
it('should be possible to navigate to the next (and previous) backend project', () => {
|
||||
cy.visit(links.backEnd1);
|
||||
cy.focused().type('{esc}').type('n');
|
||||
cy.url().should('include', links.backEnd2);
|
||||
cy.contains(titles.backEnd2);
|
||||
cy.focused().type('p');
|
||||
cy.url().should('include', links.backEnd1);
|
||||
});
|
||||
|
||||
it('should be possible to focus on the editor with pressing "e"', () => {
|
||||
cy.visit(links.classic1);
|
||||
cy.get(hotKeySelectors.editorContainer).click();
|
||||
cy.focused().as('editor').type('{esc}');
|
||||
cy.get(hotKeySelectors.instructions).click().type('e');
|
||||
cy.get('@editor').should('have.focus');
|
||||
});
|
||||
|
||||
it('should be possible to press ctrl enter to run the test', () => {
|
||||
cy.visit(links.classic1);
|
||||
cy.get(hotKeySelectors.instructions).click().type('{ctrl}{enter}');
|
||||
cy.get(selectors.dataCy.outputText).contains('// running tests');
|
||||
});
|
||||
|
||||
it('should be possible to go to navigation view by pressing escape', () => {
|
||||
cy.visit(links.classic1);
|
||||
cy.get(hotKeySelectors.editorContainer).click();
|
||||
cy.focused().as('editor').type('{esc}');
|
||||
cy.get('@editor').should('not.have.focus');
|
||||
});
|
||||
|
||||
it('it should be possible to focus on the instructions by pressing r', () => {
|
||||
cy.visit(links.classic1);
|
||||
cy.get(hotKeySelectors.editorContainer).type('{esc}');
|
||||
cy.get(selectors.dataCy.outputText).click().type('r');
|
||||
cy.get(hotKeySelectors.instructionsPanel).should('have.focus');
|
||||
});
|
||||
});
|
||||
@@ -7,6 +7,21 @@ import { getEditors } from './utils/editor';
|
||||
const course =
|
||||
'/learn/javascript-algorithms-and-data-structures/basic-javascript/comment-your-javascript-code';
|
||||
|
||||
const links = {
|
||||
frontEnd1:
|
||||
'/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-random-quote-machine',
|
||||
frontEnd2:
|
||||
'/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-markdown-previewer',
|
||||
backEnd1:
|
||||
'/learn/back-end-development-and-apis/back-end-development-and-apis-projects/timestamp-microservice',
|
||||
backEnd2:
|
||||
'learn/back-end-development-and-apis/back-end-development-and-apis-projects/request-header-parser-microservice',
|
||||
video1:
|
||||
'/learn/python-for-everybody/python-for-everybody/introduction-why-program',
|
||||
video2:
|
||||
'/learn/python-for-everybody/python-for-everybody/introduction-hardware-architecture'
|
||||
};
|
||||
|
||||
test.use({ storageState: 'playwright/.auth/certified-user.json' });
|
||||
|
||||
test.beforeAll(async ({ request }) => {
|
||||
@@ -20,6 +35,16 @@ test.beforeAll(async ({ request }) => {
|
||||
});
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/settings');
|
||||
const keyboardShortcutGroup = page.getByRole('group', {
|
||||
name: translations.settings.labels['keyboard-shortcuts']
|
||||
});
|
||||
await keyboardShortcutGroup
|
||||
.getByRole('button', { name: translations.buttons.on, exact: true })
|
||||
.click();
|
||||
});
|
||||
|
||||
test.afterEach(
|
||||
async ({ request }) =>
|
||||
await authedRequest({
|
||||
@@ -32,15 +57,7 @@ test.afterEach(
|
||||
})
|
||||
);
|
||||
|
||||
test('User can interact with the app using the keyboard', async ({ page }) => {
|
||||
// Enable keyboard shortcuts
|
||||
await page.goto('/settings');
|
||||
const keyboardShortcutGroup = page.getByRole('group', {
|
||||
name: translations.settings.labels['keyboard-shortcuts']
|
||||
});
|
||||
await keyboardShortcutGroup
|
||||
.getByRole('button', { name: translations.buttons.on, exact: true })
|
||||
.click();
|
||||
test('User can use shortcuts in and around the editor', async ({ page }) => {
|
||||
// TODO: getByRole('alert', name:
|
||||
// translations.flash['keyboard-shortcut-updated']) did not find the alert.
|
||||
// Should it a) be an alert and b) have a name?
|
||||
@@ -73,8 +90,52 @@ test('User can interact with the app using the keyboard', async ({ page }) => {
|
||||
await page.keyboard.press('e');
|
||||
await expect(getEditors(page)).toBeFocused();
|
||||
|
||||
await page.keyboard.press('Control+Enter');
|
||||
await expect(page.getByText('running test')).toBeVisible();
|
||||
|
||||
// Show shortcuts (shift+/) is covered by the shortcuts-modal tests
|
||||
await getEditors(page).press('Escape');
|
||||
await page.keyboard.press('r');
|
||||
await expect(page.locator('.instructions-panel')).toBeFocused();
|
||||
});
|
||||
|
||||
test('User can use shortcuts to navigate between frontend projects', async ({
|
||||
page
|
||||
}) => {
|
||||
await page.goto(links.frontEnd1);
|
||||
await expect(page.locator('#editor-layout')).toBeFocused();
|
||||
await page.keyboard.press('Escape');
|
||||
await page.keyboard.press('n');
|
||||
|
||||
await page.waitForURL(links.frontEnd2);
|
||||
await expect(page.locator('#editor-layout')).toBeFocused();
|
||||
await page.keyboard.press('p');
|
||||
await page.keyboard.press('Escape');
|
||||
await page.waitForURL(links.frontEnd1);
|
||||
});
|
||||
|
||||
test('User can use shortcuts to navigate between backend projects', async ({
|
||||
page
|
||||
}) => {
|
||||
await page.goto(links.backEnd1);
|
||||
await expect(page.locator('#editor-layout')).toBeFocused();
|
||||
await page.keyboard.press('Escape');
|
||||
await page.keyboard.press('n');
|
||||
|
||||
await page.waitForURL(links.backEnd2);
|
||||
await expect(page.locator('#editor-layout')).toBeFocused();
|
||||
await page.keyboard.press('p');
|
||||
await page.keyboard.press('Escape');
|
||||
await page.waitForURL(links.backEnd1);
|
||||
});
|
||||
|
||||
test('User can use shortcuts to navigate between video-based challenges', async ({
|
||||
page
|
||||
}) => {
|
||||
await page.goto(links.video1);
|
||||
await expect(page.locator('#editor-layout')).toBeFocused();
|
||||
await page.keyboard.press('Escape');
|
||||
await page.keyboard.press('n');
|
||||
|
||||
await page.waitForURL(links.video2);
|
||||
await expect(page.locator('#editor-layout')).toBeFocused();
|
||||
await page.keyboard.press('p');
|
||||
await page.keyboard.press('Escape');
|
||||
await page.waitForURL(links.video1);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user