mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
fix(learn, tools/scripts): replace archived challenge links in challenge reset modal (#64849)
Co-authored-by: Jeevankumar <jeeevnkumar2003@gmail.com> Co-authored-by: Huyen Nguyen <25715018+huyenltnguyen@users.noreply.github.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators, Dispatch } from 'redux';
|
||||
@@ -45,9 +45,13 @@ function ResetModal({
|
||||
challengeTitle
|
||||
}: ResetModalProps): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
if (isOpen) {
|
||||
callGA({ event: 'pageview', pagePath: '/reset-modal' });
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
callGA({ event: 'pageview', pagePath: '/reset-modal' });
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
return (
|
||||
<Modal onClose={close} open={isOpen} variant='danger'>
|
||||
<Modal.Header showCloseButton={true} closeButtonClassNames='close'>
|
||||
|
||||
@@ -6,6 +6,21 @@ import translations from '../client/i18n/locales/english/translations.json';
|
||||
import { clearEditor, focusEditor, getEditors } from './utils/editor';
|
||||
import { alertToBeVisible } from './utils/alerts';
|
||||
|
||||
interface ChallengeTest {
|
||||
text: string;
|
||||
testString: string;
|
||||
}
|
||||
|
||||
interface PageData {
|
||||
result: {
|
||||
data: {
|
||||
challengeNode: {
|
||||
challenge: { tests: ChallengeTest[] };
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const expectToRenderResetModal = async (page: Page) => {
|
||||
await expect(
|
||||
page.getByRole('dialog', { name: translations.learn.reset })
|
||||
@@ -29,7 +44,7 @@ const expectToRenderResetModal = async (page: Page) => {
|
||||
|
||||
test('should render the modal content correctly', async ({ page }) => {
|
||||
await page.goto(
|
||||
'/learn/2022/responsive-web-design/learn-html-by-building-a-cat-photo-app/step-3'
|
||||
'/learn/responsive-web-design-v9/workshop-cat-photo-app/step-3'
|
||||
);
|
||||
|
||||
await page.getByRole('button', { name: translations.buttons.reset }).click();
|
||||
@@ -61,7 +76,7 @@ test('User can reset challenge', async ({ page, isMobile, browserName }) => {
|
||||
.getByText(updatedText);
|
||||
|
||||
await page.goto(
|
||||
'/learn/2022/responsive-web-design/learn-html-by-building-a-cat-photo-app/step-3'
|
||||
'/learn/responsive-web-design-v9/workshop-cat-photo-app/step-3'
|
||||
);
|
||||
|
||||
// Building the preview can take a while
|
||||
@@ -103,12 +118,36 @@ test('User can reset challenge', async ({ page, isMobile, browserName }) => {
|
||||
|
||||
test.describe('When the user is not logged in', () => {
|
||||
test.use({ storageState: { cookies: [], origins: [] } });
|
||||
|
||||
test('User can reset classic challenge', async ({ page, isMobile }) => {
|
||||
await page.goto(
|
||||
'/learn/javascript-algorithms-and-data-structures/basic-javascript/comment-your-javascript-code'
|
||||
const challengePath =
|
||||
'/learn/rosetta-code/rosetta-code-challenges/100-doors';
|
||||
|
||||
// Intercept Gatsby page-data and inject a mock test that always passes
|
||||
await page.route(
|
||||
`**/page-data${challengePath}/page-data.json`,
|
||||
async route => {
|
||||
const response = await route.fetch();
|
||||
const body = await response.text();
|
||||
|
||||
const pageData = JSON.parse(body) as PageData;
|
||||
pageData.result.data.challengeNode.challenge.tests = [
|
||||
{
|
||||
text: 'Mock test',
|
||||
testString: 'assert(true)'
|
||||
}
|
||||
];
|
||||
|
||||
await route.fulfill({
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(pageData)
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
const challengeSolution = '// This is in-line comment';
|
||||
await page.goto(challengePath);
|
||||
|
||||
const challengeSolution = 'test code';
|
||||
await focusEditor({ page, isMobile });
|
||||
await getEditors(page).fill(challengeSolution);
|
||||
|
||||
@@ -117,22 +156,23 @@ test.describe('When the user is not logged in', () => {
|
||||
? translations.buttons.run
|
||||
: translations.buttons['run-test']
|
||||
});
|
||||
|
||||
await submitButton.click();
|
||||
|
||||
await expect(
|
||||
page.locator('.view-lines').getByText(challengeSolution)
|
||||
).toBeVisible();
|
||||
|
||||
if (isMobile) {
|
||||
await page
|
||||
.getByText(translations.learn['editor-tabs'].instructions)
|
||||
.click();
|
||||
}
|
||||
|
||||
// Completion dialog shows up
|
||||
await expect(
|
||||
page.getByLabel(translations.icons.passed).locator('circle')
|
||||
page.getByText(translations.buttons['go-to-next'])
|
||||
).toBeVisible();
|
||||
|
||||
// Close the dialog
|
||||
await page
|
||||
.getByRole('button', { name: translations.buttons.close })
|
||||
.click();
|
||||
|
||||
await page
|
||||
.getByRole('button', {
|
||||
name: !isMobile
|
||||
@@ -149,7 +189,7 @@ test.describe('When the user is not logged in', () => {
|
||||
page.locator('.view-lines').getByText(challengeSolution)
|
||||
).not.toBeVisible();
|
||||
await expect(
|
||||
page.getByLabel(translations.icons.passed).locator('circle')
|
||||
page.getByText(translations.buttons['go-to-next'])
|
||||
).not.toBeVisible();
|
||||
await expect(
|
||||
page.getByText(translations.learn['tests-completed'])
|
||||
@@ -167,7 +207,7 @@ test.describe('When the user is not logged in', () => {
|
||||
|
||||
test('should close when the user clicks the close button', async ({ page }) => {
|
||||
await page.goto(
|
||||
'/learn/2022/responsive-web-design/learn-html-by-building-a-cat-photo-app/step-3'
|
||||
'/learn/responsive-web-design-v9/workshop-cat-photo-app/step-3'
|
||||
);
|
||||
|
||||
await page.getByRole('button', { name: translations.buttons.reset }).click();
|
||||
@@ -195,7 +235,7 @@ test('User can reset on a multi-file project', async ({
|
||||
const sampleText = 'function palindrome() { return true; }';
|
||||
|
||||
await page.goto(
|
||||
'/learn/javascript-algorithms-and-data-structures-v8/build-a-palindrome-checker-project/build-a-palindrome-checker'
|
||||
'/learn/javascript-v9/lab-palindrome-checker/build-a-palindrome-checker'
|
||||
);
|
||||
|
||||
await focusEditor({ page, isMobile });
|
||||
@@ -245,7 +285,7 @@ test.describe('Signed in user', () => {
|
||||
const updatedText = 'function palindrome() { return false; }';
|
||||
|
||||
await page.goto(
|
||||
'/learn/javascript-algorithms-and-data-structures-v8/build-a-palindrome-checker-project/build-a-palindrome-checker'
|
||||
'/learn/javascript-v9/lab-palindrome-checker/build-a-palindrome-checker'
|
||||
);
|
||||
|
||||
// This first edit should reappear after the reset
|
||||
@@ -286,7 +326,7 @@ test.describe('Signed in user', () => {
|
||||
const updatedText = 'function palindrome() { return false; }';
|
||||
|
||||
await page.goto(
|
||||
'/learn/javascript-algorithms-and-data-structures-v8/build-a-palindrome-checker-project/build-a-palindrome-checker'
|
||||
'/learn/javascript-v9/lab-palindrome-checker/build-a-palindrome-checker'
|
||||
);
|
||||
|
||||
// This first edit should reappear after the reset
|
||||
|
||||
Reference in New Issue
Block a user