Skip to content

Commit

Permalink
feat: convert "navigation tests spec" to Playwright (freeCodeCamp#54944)
Browse files Browse the repository at this point in the history
Co-authored-by: Huyen Nguyen <[email protected]>
  • Loading branch information
Sembauke and huyenltnguyen authored May 25, 2024
1 parent 58b3218 commit 020a8c5
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 20 deletions.
2 changes: 1 addition & 1 deletion cypress/e2e/default/learn/challenges/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const challenge2 = {
const rwdChallenge = {
url: '/learn/2022/responsive-web-design/build-a-personal-portfolio-webpage-project/build-a-personal-portfolio-webpage',
nextUrl:
'http://localhost:8000/learn/2022/responsive-web-design/#build-a-personal-portfolio-webpage-project'
'/learn/2022/responsive-web-design/#build-a-personal-portfolio-webpage-project'
};

const rwdChallengeSolution = `<head>
Expand Down
2 changes: 1 addition & 1 deletion e2e/challenge-reset-modal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ test('User can reset challenge', async ({ page, isMobile, browserName }) => {

// Modify the text in the editor pane, clearing first, otherwise the existing
// text will be selected before typing
await focusEditor({ page, isMobile, browserName });
await focusEditor({ page, isMobile });
await clearEditor({ page, browserName });
await getEditors(page).fill(updatedText);
await expect(updatedFrame).toBeVisible({ timeout: 10000 });
Expand Down
2 changes: 1 addition & 1 deletion e2e/editor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ test.describe('Python Terminal', () => {
'learn/scientific-computing-with-python/learn-string-manipulation-by-building-a-cipher/step-2'
);

await focusEditor({ page, isMobile, browserName });
await focusEditor({ page, isMobile });
await clearEditor({ page, browserName });
// Then enter invalid code
await page.keyboard.insertText('def');
Expand Down
3 changes: 3 additions & 0 deletions e2e/fixtures/build-a-personal-portfolio-webpage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"content": "<head><style>@media (max-width: 500px){nav{display: none;}}</style></head><body><nav id=\"navbar\"><a href=\"#projects\">text</a> | </nav><main><section id=\"welcome-section\"><h1>text</h1></section><hr><section id=\"projects\"><h1>Projects</h1><h2 class=\"project-tile\"><a id=\"profile-link\" target=\"_blank\" href=\"https://freecodecamp.org\">text</a></h2></section><hr></body></html>"
}
2 changes: 1 addition & 1 deletion e2e/lower-jaw.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ test('Prompts unauthenticated user to sign in to save progress', async ({
const loginButton = page.getByRole('link', {
name: 'Sign in to save your progress'
});
await focusEditor({ page, browserName, isMobile });
await focusEditor({ page, isMobile });
await clearEditor({ page, browserName });

await editor.fill(
Expand Down
90 changes: 90 additions & 0 deletions e2e/navigation-from-last-challenge.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { test } from '@playwright/test';
import solution from './fixtures/build-a-personal-portfolio-webpage.json';
import { clearEditor, focusEditor } from './utils/editor';
import { isMacOS } from './utils/user-agent';

// middle of block
const challenge1 = {
url: '/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-javascript-calculator',
nextUrl:
'/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-25--5-clock'
};

// last in superblock
const challenge2 = {
url: '/learn/college-algebra-with-python/build-a-data-graph-explorer-project/build-a-data-graph-explorer',
nextUrl:
'/learn/college-algebra-with-python/#build-a-data-graph-explorer-project'
};

const rwdChallenge = {
url: '/learn/2022/responsive-web-design/build-a-personal-portfolio-webpage-project/build-a-personal-portfolio-webpage',
nextUrl:
'/learn/2022/responsive-web-design/#build-a-personal-portfolio-webpage-project'
};
test.use({ storageState: 'playwright/.auth/certified-user.json' });
test.describe('Navigation from the middle or end (URL solution)', () => {
test('In the middle of a block should take you to the next challenge', async ({
page
}) => {
await page.goto(challenge1.url);
await page
.getByRole('textbox', { name: 'solution' })
.fill('https://example.com');
await page.keyboard.press('Enter');
await page
.getByRole('button', { name: 'Submit and go to next challenge' })
.click();
await page.waitForURL(challenge1.nextUrl);
});

test('at the end of a superblock should take you to the superblock page with the current block hash', async ({
page
}) => {
await page.goto(challenge2.url);
await page
.getByRole('textbox', { name: 'solution' })
.fill('https://example.com');
await page.keyboard.press('Enter');
await page
.getByRole('button', { name: 'Submit and go to next challenge' })
.click();
await page.waitForURL(challenge2.nextUrl);
});
});

test.describe('Should take you to the next superblock (with editor solution)', () => {
test.skip(
({ browserName }) => browserName !== 'chromium',
'Only chromium allows us to use the clipboard API.'
);
test('at the end of a superblock should take you to the superblock page with the current block hash', async ({
page,
isMobile,
browserName,
context
}) => {
await context.grantPermissions(['clipboard-read', 'clipboard-write']);
await page.goto(rwdChallenge.url);
await focusEditor({ page, isMobile });
await clearEditor({ page, browserName });

await page.evaluate(
async solution => await navigator.clipboard.writeText(solution.content),
solution
);

if (isMacOS) {
await page.keyboard.press('Meta+v');
} else {
await page.keyboard.press('Control+v');
}

await page.keyboard.press('Control+Enter');

await page
.getByRole('button', { name: 'Submit and go to next challenge' })
.click();
await page.waitForURL(rwdChallenge.nextUrl);
});
});
3 changes: 1 addition & 2 deletions e2e/preview.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ test.describe('Challenge Preview Component', () => {

test('should render correct output of changed code', async ({
page,
browserName,
isMobile
}) => {
await focusEditor({ page, isMobile, browserName });
await focusEditor({ page, isMobile });

await page.keyboard.insertText('<h1>FreeCodeCamp</h1>');
if (isMobile) {
Expand Down
2 changes: 1 addition & 1 deletion e2e/progress-bar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ test.describe('Progress bar component', () => {
// 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 focusEditor({ page, isMobile });
await clearEditor({ page, browserName });

await page.keyboard.insertText(
Expand Down
2 changes: 1 addition & 1 deletion e2e/projects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ test.describe('JavaScript projects can be submitted and then viewed in /settings
'/learn/javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects/palindrome-checker'
);

await focusEditor({ page, browserName, isMobile });
await focusEditor({ page, isMobile });
await clearEditor({ page, browserName });

await page.evaluate(
Expand Down
14 changes: 2 additions & 12 deletions e2e/utils/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ export const getEditors = (page: Page) => {

export const focusEditor = async ({
page,
isMobile,
browserName
isMobile
}: {
page: Page;
isMobile: boolean;
browserName: string;
}) => {
if (isMobile) {
const codeBtn = page.getByRole('tab', { name: 'Code' });
Expand All @@ -23,15 +21,7 @@ export const focusEditor = async ({
await codeBtn.click({ force: true });
}

// 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();
}
await getEditors(page).focus();
};

export async function clearEditor({
Expand Down

0 comments on commit 020a8c5

Please sign in to comment.