mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-02-14 07:00:56 -05:00
refactor(e2e): create editor helpers (#54701)
This commit is contained in:
committed by
GitHub
parent
c7d3b1303e
commit
ca4e5db8b1
@@ -1,4 +1,7 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
import { getEditors } from './utils/editor';
|
||||
|
||||
test.use({ storageState: 'playwright/.auth/certified-user.json' });
|
||||
test.describe('Challenge with editor', function () {
|
||||
test('the shortcut "Ctrl + S" saves the code', async ({ page }) => {
|
||||
@@ -6,7 +9,7 @@ test.describe('Challenge with editor', function () {
|
||||
'/learn/2022/responsive-web-design/learn-html-by-building-a-cat-photo-app/step-2'
|
||||
);
|
||||
|
||||
const editor = page.locator('textarea');
|
||||
const editor = getEditors(page);
|
||||
|
||||
await editor.fill('Something funny');
|
||||
await page.keyboard.down('Control');
|
||||
|
||||
@@ -1,26 +1,6 @@
|
||||
import { expect, test, type Page } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
async function focusEditor({
|
||||
page,
|
||||
isMobile,
|
||||
browserName
|
||||
}: {
|
||||
page: Page;
|
||||
isMobile: boolean;
|
||||
browserName: string;
|
||||
}) {
|
||||
const monacoEditor = page.getByLabel('Editor content');
|
||||
|
||||
// The editor has an overlay div, which prevents the click event from bubbling up in iOS Safari.
|
||||
// This is a quirk in this browser-OS combination, and the workaround here is to use `.focus()`
|
||||
// in place of `.click()` to focus on the editor.
|
||||
// Ref: https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
||||
if (isMobile && browserName === 'webkit') {
|
||||
await monacoEditor.focus();
|
||||
} else {
|
||||
await monacoEditor.click();
|
||||
}
|
||||
}
|
||||
import { clearEditor, focusEditor } from './utils/editor';
|
||||
|
||||
test.describe('Editor Component', () => {
|
||||
test('should allow the user to insert text', async ({
|
||||
@@ -50,14 +30,7 @@ test.describe('Python Terminal', () => {
|
||||
);
|
||||
|
||||
await focusEditor({ page, isMobile, browserName });
|
||||
// First clear the editor
|
||||
// TODO: replace with ControlOrMeta when it's supported
|
||||
if (browserName === 'webkit') {
|
||||
await page.keyboard.press('Meta+a');
|
||||
} else {
|
||||
await page.keyboard.press('Control+a');
|
||||
}
|
||||
await page.keyboard.press('Backspace');
|
||||
await clearEditor({ page, browserName });
|
||||
// Then enter invalid code
|
||||
await page.keyboard.insertText('def');
|
||||
const preview = page.getByTestId('preview-pane');
|
||||
|
||||
@@ -2,11 +2,10 @@ import { test, expect } from '@playwright/test';
|
||||
|
||||
import translations from '../client/i18n/locales/english/translations.json';
|
||||
import { authedPut } from './utils/request';
|
||||
import { getEditors } from './utils/editor';
|
||||
|
||||
const course =
|
||||
'/learn/javascript-algorithms-and-data-structures/basic-javascript/comment-your-javascript-code';
|
||||
const editorPaneLabel =
|
||||
'Editor content;Press Alt+F1 for Accessibility Options.';
|
||||
|
||||
test.use({ storageState: 'playwright/.auth/certified-user.json' });
|
||||
|
||||
@@ -41,9 +40,9 @@ test('User can interact with the app using the keyboard', async ({ page }) => {
|
||||
|
||||
await page.goto(course);
|
||||
|
||||
await expect(page.getByLabel(editorPaneLabel)).toBeFocused();
|
||||
await page.getByLabel(editorPaneLabel).press('Escape');
|
||||
await expect(page.getByLabel(editorPaneLabel)).not.toBeFocused();
|
||||
await expect(getEditors(page)).toBeFocused();
|
||||
await getEditors(page).press('Escape');
|
||||
await expect(getEditors(page)).not.toBeFocused();
|
||||
|
||||
await page.keyboard.press('n');
|
||||
const nextCourse = '**/declare-javascript-variables';
|
||||
@@ -62,7 +61,7 @@ test('User can interact with the app using the keyboard', async ({ page }) => {
|
||||
).toBeVisible();
|
||||
|
||||
await page.keyboard.press('e');
|
||||
await expect(page.getByLabel(editorPaneLabel)).toBeFocused();
|
||||
await expect(getEditors(page)).toBeFocused();
|
||||
|
||||
await page.keyboard.press('Control+Enter');
|
||||
await expect(page.getByText('running test')).toBeVisible();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
import { getEditors } from './utils/editor';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto(
|
||||
'/learn/2022/responsive-web-design/learn-basic-css-by-building-a-cafe-menu/step-15'
|
||||
@@ -21,7 +23,7 @@ test.describe('MultifileEditor Component', () => {
|
||||
// before moving onto other assertions.
|
||||
// Note that using the `.all()` locator here would result a flaky test.
|
||||
// Ref: https://github.com/freeCodeCamp/freeCodeCamp/pull/53031/files#r1500316812
|
||||
const editors = page.getByLabel('Editor content');
|
||||
const editors = getEditors(page);
|
||||
await expect(editors).toHaveCount(2);
|
||||
|
||||
const test_string = 'TestString';
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
|
||||
import translations from '../client/i18n/locales/english/translations.json';
|
||||
import { getEditors } from './utils/editor';
|
||||
|
||||
const outputTexts = {
|
||||
default: `
|
||||
@@ -33,7 +35,7 @@ const insertTextInCodeEditor = async ({
|
||||
.getByRole('tab', { name: translations.learn['editor-tabs'].code })
|
||||
.click();
|
||||
}
|
||||
await page.getByLabel('Editor content').fill(text);
|
||||
await getEditors(page).fill(text);
|
||||
if (isMobile) {
|
||||
await page
|
||||
.getByRole('tab', { name: translations.learn['editor-tabs'].console })
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import translations from '../client/i18n/locales/english/translations.json';
|
||||
import { focusEditor } from './utils/editor';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto(
|
||||
@@ -30,15 +31,7 @@ test.describe('Challenge Preview Component', () => {
|
||||
browserName,
|
||||
isMobile
|
||||
}) => {
|
||||
// The editor has an overlay div, which prevents the click event from bubbling up in iOS Safari.
|
||||
// This is a quirk in this browser-OS combination, and the workaround here is to use `.focus()`
|
||||
// in place of `.click()` to focus on the editor.
|
||||
// Ref: https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
||||
if (isMobile && browserName === 'webkit') {
|
||||
await page.getByLabel('Editor content').focus();
|
||||
} else {
|
||||
await page.getByLabel('Editor content').click();
|
||||
}
|
||||
await focusEditor({ page, isMobile, browserName });
|
||||
|
||||
await page.keyboard.insertText('<h1>FreeCodeCamp</h1>');
|
||||
if (isMobile) {
|
||||
|
||||
@@ -1,26 +1,25 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { clearEditor, focusEditor } from './utils/editor';
|
||||
|
||||
test.use({ storageState: 'playwright/.auth/certified-user.json' });
|
||||
|
||||
test.describe('Progress bar component', () => {
|
||||
test('Should appear with the correct content after the user has submitted their code', async ({
|
||||
page
|
||||
page,
|
||||
isMobile,
|
||||
browserName
|
||||
}) => {
|
||||
await page.goto(
|
||||
'/learn/2022/responsive-web-design/learn-html-by-building-a-cat-photo-app/step-2'
|
||||
'/learn/2022/responsive-web-design/learn-html-by-building-a-cat-photo-app/step-3'
|
||||
);
|
||||
|
||||
const monacoEditor = page.getByLabel('Editor content');
|
||||
|
||||
// Using focus instead of click since we're not testing if the editor
|
||||
// behaves correctly, we're using it to complete the challenge.
|
||||
await monacoEditor.focus();
|
||||
await page.keyboard.press('Control+A');
|
||||
//Meta + A works in webkit
|
||||
await page.keyboard.press('Meta+A');
|
||||
await page.keyboard.press('Backspace');
|
||||
// If focusEditor fails, typically it's because the instructions are too
|
||||
// large. There's a bug that means `scrollIntoView` does not work in the
|
||||
// editor and so we have to pick less verbose challenges until that's fixed.
|
||||
await focusEditor({ page, isMobile, browserName });
|
||||
await clearEditor({ page, browserName });
|
||||
|
||||
await page.keyboard.insertText(
|
||||
'<html><body><h1>CatPhotoApp</h1><h2>Cat Photos</h2></body></html>'
|
||||
'<html><body><h1>CatPhotoApp</h1><h2>Cat Photos</h2><p>See more cat photos in our gallery.</p></body></html>'
|
||||
);
|
||||
|
||||
await page.getByRole('button', { name: 'Check Your Code' }).click();
|
||||
@@ -36,19 +35,15 @@ test.describe('Progress bar component', () => {
|
||||
});
|
||||
|
||||
test('should appear in the completion modal after user has submitted their code', async ({
|
||||
page
|
||||
page,
|
||||
isMobile,
|
||||
browserName
|
||||
}) => {
|
||||
await page.goto(
|
||||
'/learn/javascript-algorithms-and-data-structures/basic-javascript/declare-javascript-variables'
|
||||
);
|
||||
|
||||
const monacoEditor = page.getByLabel('Editor content');
|
||||
await monacoEditor.focus();
|
||||
|
||||
await page.keyboard.press('Control+A');
|
||||
|
||||
await page.keyboard.press('Meta+A');
|
||||
await page.keyboard.press('Backspace');
|
||||
await focusEditor({ page, isMobile, browserName });
|
||||
await clearEditor({ page, browserName });
|
||||
|
||||
await page.keyboard.insertText('var myName;');
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
import translations from '../client/i18n/locales/english/translations.json';
|
||||
import { clearEditor, focusEditor, getEditors } from './utils/editor';
|
||||
|
||||
test('should render the modal content correctly', async ({ page }) => {
|
||||
await page.goto(
|
||||
@@ -36,7 +37,7 @@ test('should render the modal content correctly', async ({ page }) => {
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test('User can reset challenge', async ({ page }) => {
|
||||
test('User can reset challenge', async ({ page, isMobile, browserName }) => {
|
||||
const initialText = 'CatPhotoApp';
|
||||
const initialFrame = page
|
||||
.frameLocator('iframe[title="challenge preview"]')
|
||||
@@ -54,13 +55,11 @@ test('User can reset challenge', async ({ page }) => {
|
||||
// Building the preview can take a while
|
||||
await expect(initialFrame).toBeVisible({ timeout: 10000 });
|
||||
|
||||
const editorPaneLabel =
|
||||
'Editor content;Press Alt+F1 for Accessibility Options.';
|
||||
|
||||
// Modify the text in the editor pane, clearing first, otherwise the existing
|
||||
// text will be selected before typing
|
||||
await page.getByLabel(editorPaneLabel).fill('');
|
||||
await page.getByLabel(editorPaneLabel).fill(updatedText);
|
||||
await focusEditor({ page, isMobile, browserName });
|
||||
await clearEditor({ page, browserName });
|
||||
await getEditors(page).fill(updatedText);
|
||||
await expect(updatedFrame).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Run the tests so the lower jaw updates (later we confirm that the update
|
||||
@@ -95,11 +94,9 @@ test('User can reset classic challenge', async ({ page, isMobile }) => {
|
||||
'/learn/javascript-algorithms-and-data-structures/basic-javascript/comment-your-javascript-code'
|
||||
);
|
||||
|
||||
const editorPaneLabel =
|
||||
'Editor content;Press Alt+F1 for Accessibility Options.';
|
||||
const challengeSolution = '// This is in-line comment';
|
||||
|
||||
await page.getByLabel(editorPaneLabel).fill(challengeSolution);
|
||||
await getEditors(page).fill(challengeSolution);
|
||||
|
||||
const submitButton = page.getByRole('button', {
|
||||
name: isMobile ? translations.buttons.run : translations.buttons['run-test']
|
||||
|
||||
@@ -2,11 +2,10 @@ import { APIRequestContext, Page, expect, test } from '@playwright/test';
|
||||
|
||||
import translations from '../client/i18n/locales/english/translations.json';
|
||||
import { authedPut } from './utils/request';
|
||||
import { getEditors } from './utils/editor';
|
||||
|
||||
const course =
|
||||
'/learn/javascript-algorithms-and-data-structures/basic-javascript/comment-your-javascript-code';
|
||||
const editorPaneLabel =
|
||||
'Editor content;Press Alt+F1 for Accessibility Options.';
|
||||
|
||||
test.use({ storageState: 'playwright/.auth/certified-user.json' });
|
||||
|
||||
@@ -23,7 +22,7 @@ const enableKeyboardShortcuts = async (request: APIRequestContext) => {
|
||||
const openModal = async (page: Page) => {
|
||||
// The editor pane is focused by default, so we need to escape or it will
|
||||
// capture the keyboard shortcuts
|
||||
await page.getByLabel(editorPaneLabel).press('Escape');
|
||||
await getEditors(page).press('Escape');
|
||||
await page.keyboard.press('Shift+?');
|
||||
};
|
||||
|
||||
|
||||
48
e2e/utils/editor.ts
Normal file
48
e2e/utils/editor.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { type Page } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* Retrieves any editor elements on the page.
|
||||
* @param page - The Playwright page object.
|
||||
* @returns The editor elements.
|
||||
*/
|
||||
export function getEditors(page: Page) {
|
||||
return page.getByLabel(
|
||||
'Editor content;Press Alt+F1 for Accessibility Options'
|
||||
);
|
||||
}
|
||||
|
||||
export async function focusEditor({
|
||||
page,
|
||||
isMobile,
|
||||
browserName
|
||||
}: {
|
||||
page: Page;
|
||||
isMobile: boolean;
|
||||
browserName: string;
|
||||
}) {
|
||||
// The editor has an overlay div, which prevents the click event from bubbling up in iOS Safari.
|
||||
// This is a quirk in this browser-OS combination, and the workaround here is to use `.focus()`
|
||||
// in place of `.click()` to focus on the editor.
|
||||
// Ref: https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
||||
if (isMobile && browserName === 'webkit') {
|
||||
await getEditors(page).focus();
|
||||
} else {
|
||||
await getEditors(page).click();
|
||||
}
|
||||
}
|
||||
|
||||
export async function clearEditor({
|
||||
page,
|
||||
browserName
|
||||
}: {
|
||||
page: Page;
|
||||
browserName: string;
|
||||
}) {
|
||||
// TODO: replace with ControlOrMeta when it's supported
|
||||
if (browserName === 'webkit') {
|
||||
await page.keyboard.press('Meta+a');
|
||||
} else {
|
||||
await page.keyboard.press('Control+a');
|
||||
}
|
||||
await page.keyboard.press('Backspace');
|
||||
}
|
||||
Reference in New Issue
Block a user