feat(client): archive page (#62450)

This commit is contained in:
Tom
2025-10-02 14:30:33 -05:00
committed by GitHub
parent 8704883aeb
commit 0b71e8779d
13 changed files with 206 additions and 125 deletions

44
e2e/archive.spec.ts Normal file
View File

@@ -0,0 +1,44 @@
import { expect, test } from '@playwright/test';
import intro from '../client/i18n/locales/english/intro.json';
import { SuperBlocks } from '../shared/config/curriculum';
const archivedSuperBlocks = [
intro[SuperBlocks.RespWebDesignNew].title,
intro[SuperBlocks.JsAlgoDataStructNew].title,
intro[SuperBlocks.FrontEndDevLibs].title,
intro[SuperBlocks.DataVis].title,
intro[SuperBlocks.RelationalDb].title,
intro[SuperBlocks.BackEndDevApis].title,
intro[SuperBlocks.QualityAssurance].title,
intro[SuperBlocks.SciCompPy].title,
intro[SuperBlocks.DataAnalysisPy].title,
intro[SuperBlocks.InfoSec].title,
intro[SuperBlocks.MachineLearningPy].title,
intro[SuperBlocks.CollegeAlgebraPy].title,
intro[SuperBlocks.RespWebDesign].title,
intro[SuperBlocks.JsAlgoDataStruct].title,
intro[SuperBlocks.PythonForEverybody].title
];
test.describe('Archive Page', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/learn/archive');
});
test('Links to new curriculum', async ({ page }) => {
const newCurriculumLink = page.locator(
'a[href="/learn/full-stack-developer"]'
);
await expect(newCurriculumLink).toBeVisible();
});
test('Links to all archived superblocks in order', async ({ page }) => {
const curriculumBtns = page.getByTestId('curriculum-map-button');
await expect(curriculumBtns).toHaveCount(archivedSuperBlocks.length);
for (let index = 0; index < archivedSuperBlocks.length; index++) {
const btn = curriculumBtns.nth(index);
const link = btn.getByRole('link', { name: archivedSuperBlocks[index] });
await expect(link).toBeVisible();
}
});
});

View File

@@ -15,7 +15,7 @@ const landingPageElements = {
jobs: 'More than <strong>100,000</strong> freeCodeCamp.org graduates have gotten <strong>jobs</strong> at tech companies including:'
} as const;
const superBlocks = [
const nonArchivedSuperBlocks = [
intro[SuperBlocks.FullStackDeveloper].title,
intro[SuperBlocks.A2English].title,
intro[SuperBlocks.B1English].title,
@@ -23,21 +23,6 @@ const superBlocks = [
intro[SuperBlocks.CodingInterviewPrep].title,
intro[SuperBlocks.ProjectEuler].title,
intro[SuperBlocks.RosettaCode].title,
intro[SuperBlocks.RespWebDesignNew].title,
intro[SuperBlocks.JsAlgoDataStructNew].title,
intro[SuperBlocks.FrontEndDevLibs].title,
intro[SuperBlocks.DataVis].title,
intro[SuperBlocks.RelationalDb].title,
intro[SuperBlocks.BackEndDevApis].title,
intro[SuperBlocks.QualityAssurance].title,
intro[SuperBlocks.SciCompPy].title,
intro[SuperBlocks.DataAnalysisPy].title,
intro[SuperBlocks.InfoSec].title,
intro[SuperBlocks.MachineLearningPy].title,
intro[SuperBlocks.CollegeAlgebraPy].title,
intro[SuperBlocks.RespWebDesign].title,
intro[SuperBlocks.JsAlgoDataStruct].title,
intro[SuperBlocks.PythonForEverybody].title,
intro[SuperBlocks.FoundationalCSharp].title
];
@@ -209,16 +194,23 @@ test.describe('Landing Page', () => {
}
});
test('Links to all superblocks in order', async ({ page }) => {
test('Links to all non-archived superblocks in order', async ({ page }) => {
const curriculumBtns = page.getByTestId(landingPageElements.curriculumBtns);
await expect(curriculumBtns).toHaveCount(superBlocks.length);
for (let index = 0; index < superBlocks.length; index++) {
await expect(curriculumBtns).toHaveCount(nonArchivedSuperBlocks.length);
for (let index = 0; index < nonArchivedSuperBlocks.length; index++) {
const btn = curriculumBtns.nth(index);
const link = btn.getByRole('link', { name: superBlocks[index] });
const link = btn.getByRole('link', {
name: nonArchivedSuperBlocks[index]
});
await expect(link).toBeVisible();
}
});
test('Links to the archive page', async ({ page }) => {
const archiveLink = page.locator('a[href="/learn/archive"]');
await expect(archiveLink).toBeVisible();
});
test('Has FAQ section', async ({ page }) => {
const faqs = page.getByTestId(landingPageElements.faq);
await expect(faqs).toHaveCount(9);

View File

@@ -6,42 +6,6 @@ test.beforeEach(async ({ page }) => {
});
const LANDING_PAGE_LINKS = [
{
slug: '2022/responsive-web-design',
name: 'Responsive Web Design'
},
{
slug: 'javascript-algorithms-and-data-structures-v8',
name: 'JavaScript Algorithms and Data Structures'
},
{
slug: 'front-end-development-libraries',
name: 'Front End Development Libraries'
},
{ slug: 'data-visualization', name: 'Data Visualization' },
{ slug: 'relational-database', name: 'Relational Database' },
{
slug: 'back-end-development-and-apis',
name: 'Back End Development and APIs'
},
{ slug: 'quality-assurance', name: 'Quality Assurance' },
{
slug: 'scientific-computing-with-python',
name: 'Scientific Computing with Python'
},
{
slug: 'data-analysis-with-python',
name: 'Data Analysis with Python'
},
{ slug: 'information-security', name: 'Information Security' },
{
slug: 'machine-learning-with-python',
name: 'Machine Learning with Python'
},
{
slug: 'college-algebra-with-python',
name: 'College Algebra with Python'
},
{
slug: 'full-stack-developer',
name: 'Certified Full Stack Developer Curriculum'
@@ -61,16 +25,7 @@ const LANDING_PAGE_LINKS = [
{ slug: 'the-odin-project', name: 'The Odin Project - freeCodeCamp Remix' },
{ slug: 'coding-interview-prep', name: 'Coding Interview Prep' },
{ slug: 'project-euler', name: 'Project Euler' },
{ slug: 'rosetta-code', name: 'Rosetta Code' },
{
slug: 'responsive-web-design',
name: 'Legacy Responsive Web Design Challenges'
},
{
slug: 'javascript-algorithms-and-data-structures',
name: 'Legacy JavaScript Algorithms and Data Structures'
},
{ slug: 'python-for-everybody', name: 'Legacy Python for Everybody' }
{ slug: 'rosetta-code', name: 'Rosetta Code' }
];
test.describe('Map Component', () => {
@@ -85,7 +40,7 @@ test.describe('Map Component', () => {
page.getByText(translations.landing['interview-prep-heading'])
).toBeVisible();
const curriculumBtns = page.getByTestId('curriculum-map-button');
await expect(curriculumBtns).toHaveCount(23);
await expect(curriculumBtns).toHaveCount(8);
for (const { name, slug } of LANDING_PAGE_LINKS) {
const superblockLink = page.getByRole('link', {