mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
feat: re-enable all ci (#52640)
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
name: CI - E2E - Playwright
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: ['CI - Node.js']
|
||||
types:
|
||||
- completed
|
||||
# TODO: refactor with a workflow_call
|
||||
push:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
branches:
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
name: CI - E2E - Web browser
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: ['CI - Node.js']
|
||||
types:
|
||||
- completed
|
||||
# TODO: refactor with a workflow_call
|
||||
push:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
branches:
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
name: CI - E2E - Containers
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: ['CI - Node.js']
|
||||
types:
|
||||
- completed
|
||||
# TODO: refactor with a workflow_call
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
branches:
|
||||
- 'main'
|
||||
- 'next-**'
|
||||
- 'e2e-**'
|
||||
|
||||
jobs:
|
||||
build-client:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"dashedName": "build-a-pokemon-search-app-project",
|
||||
"usesMultifileEditor": true,
|
||||
"helpCategory": "JavaScript",
|
||||
"order": 99,
|
||||
"order": 20,
|
||||
"time": "30 hours",
|
||||
"template": "",
|
||||
"required": [],
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "rosetta-code-challenges",
|
||||
"helpCategory": "Rosetta",
|
||||
"order": 3,
|
||||
"order": 0,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
|
||||
@@ -42,8 +42,7 @@ const { getLines } = require('../../shared/utils/get-lines');
|
||||
|
||||
const { getChallengesForLang, getMetaForBlock } = require('../get-challenges');
|
||||
const { challengeSchemaValidator } = require('../schema/challenge-schema');
|
||||
// const { testedLang, getSuperOrder } = require('../utils');
|
||||
const { testedLang } = require('../utils');
|
||||
const { testedLang, getSuperOrder } = require('../utils');
|
||||
const ChallengeTitles = require('./utils/challenge-titles');
|
||||
const MongoIds = require('./utils/mongo-ids');
|
||||
const createPseudoWorker = require('./utils/pseudo-worker');
|
||||
@@ -276,50 +275,49 @@ function populateTestsForLang({ lang, challenges, meta }) {
|
||||
const challengeTitles = new ChallengeTitles();
|
||||
const validateChallenge = challengeSchemaValidator();
|
||||
|
||||
// if (!process.env.FCC_BLOCK && !process.env.FCC_CHALLENGE_ID) {
|
||||
// describe('Assert meta order', function () {
|
||||
// /** This array can be used to skip a superblock - we'll use this
|
||||
// * when we are working on the new project-based curriculum for
|
||||
// * a superblock (because keeping those challenges in order is
|
||||
// * tricky and needs cleaning up before deploying).
|
||||
// */
|
||||
// const superBlocksUnderDevelopment = [
|
||||
// ];
|
||||
// const superBlocks = new Set([
|
||||
// ...Object.values(meta)
|
||||
// .map(el => el.superBlock)
|
||||
// .filter(el => !superBlocksUnderDevelopment.includes(el))
|
||||
// ]);
|
||||
// superBlocks.forEach(superBlock => {
|
||||
// const filteredMeta = Object.values(meta)
|
||||
// .filter(el => el.superBlock === superBlock)
|
||||
// .sort((a, b) => a.order - b.order);
|
||||
// if (!filteredMeta.length) {
|
||||
// return;
|
||||
// }
|
||||
// it(`${superBlock} should have the same order in every meta`, function () {
|
||||
// const firstOrder = getSuperOrder(filteredMeta[0].superBlock, {
|
||||
// showNewCurriculum: process.env.SHOW_NEW_CURRICULUM
|
||||
// });
|
||||
// assert.isNumber(firstOrder);
|
||||
// assert.isTrue(
|
||||
// filteredMeta.every(
|
||||
// el =>
|
||||
// getSuperOrder(el.superBlock, {
|
||||
// showNewCurriculum: process.env.SHOW_NEW_CURRICULUM
|
||||
// }) === firstOrder
|
||||
// ),
|
||||
// 'The superOrder properties are mismatched.'
|
||||
// );
|
||||
// });
|
||||
// filteredMeta.forEach((meta, index) => {
|
||||
// it(`${meta.superBlock} ${meta.name} must be in order`, function () {
|
||||
// assert.equal(meta.order, index);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
if (!process.env.FCC_BLOCK && !process.env.FCC_CHALLENGE_ID) {
|
||||
describe('Assert meta order', function () {
|
||||
/** This array can be used to skip a superblock - we'll use this
|
||||
* when we are working on the new project-based curriculum for
|
||||
* a superblock (because keeping those challenges in order is
|
||||
* tricky and needs cleaning up before deploying).
|
||||
*/
|
||||
const superBlocksUnderDevelopment = ['scientific-computing-with-python'];
|
||||
const superBlocks = new Set([
|
||||
...Object.values(meta)
|
||||
.map(el => el.superBlock)
|
||||
.filter(el => !superBlocksUnderDevelopment.includes(el))
|
||||
]);
|
||||
superBlocks.forEach(superBlock => {
|
||||
const filteredMeta = Object.values(meta)
|
||||
.filter(el => el.superBlock === superBlock)
|
||||
.sort((a, b) => a.order - b.order);
|
||||
if (!filteredMeta.length) {
|
||||
return;
|
||||
}
|
||||
it(`${superBlock} should have the same order in every meta`, function () {
|
||||
const firstOrder = getSuperOrder(filteredMeta[0].superBlock, {
|
||||
showNewCurriculum: process.env.SHOW_NEW_CURRICULUM
|
||||
});
|
||||
assert.isNumber(firstOrder);
|
||||
assert.isTrue(
|
||||
filteredMeta.every(
|
||||
el =>
|
||||
getSuperOrder(el.superBlock, {
|
||||
showNewCurriculum: process.env.SHOW_NEW_CURRICULUM
|
||||
}) === firstOrder
|
||||
),
|
||||
'The superOrder properties are mismatched.'
|
||||
);
|
||||
});
|
||||
filteredMeta.forEach((meta, index) => {
|
||||
it(`${meta.superBlock} ${meta.name} must be in order`, function () {
|
||||
assert.equal(meta.order, index);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe(`Check challenges (${lang})`, function () {
|
||||
this.timeout(5000);
|
||||
|
||||
@@ -8,9 +8,9 @@ describe('Settings certifications area', () => {
|
||||
});
|
||||
|
||||
it('Should render the default settings page', () => {
|
||||
cy.visit('/settings/');
|
||||
cy.visit('/settings');
|
||||
cy.findAllByText('Claim Certification').should($btns => {
|
||||
expect($btns).to.have.length(18);
|
||||
expect($btns).to.have.length(19);
|
||||
});
|
||||
cy.findByText('Show Certification').should('not.exist');
|
||||
cy.contains(`I agree to freeCodeCamp's Academic Honesty Policy.`);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const challenges = {
|
||||
responsiveWebDesign:
|
||||
'/learn/responsive-web-design/basic-html-and-html5/say-hello-to-html-elements',
|
||||
rosettaCode: '/learn/rosetta-code/100-doors',
|
||||
rosettaCode: '/learn/rosetta-code/rosetta-code-challenges/100-doors',
|
||||
projectEuler:
|
||||
'/learn/project-euler/project-euler-problems-1-to-100/problem-1-multiples-of-3-and-5'
|
||||
};
|
||||
|
||||
+32
-26
@@ -4,23 +4,29 @@ import words from '../client/i18n/locales/english/motivation.json';
|
||||
|
||||
let page: Page;
|
||||
|
||||
// const superBlocks = [
|
||||
// 'Responsive Web Design',
|
||||
// 'JavaScript Algorithms and Data Structures',
|
||||
// 'Front End Development Libraries',
|
||||
// 'Data Visualization',
|
||||
// 'Relational Database',
|
||||
// 'Back End Development and APIs',
|
||||
// 'Quality Assurance',
|
||||
// 'Scientific Computing with Python',
|
||||
// 'Data Analysis with Python',
|
||||
// 'Information Security',
|
||||
// 'Machine Learning with Python',
|
||||
// 'College Algebra with Python',
|
||||
// 'Foundational C# with Microsoft',
|
||||
// 'Coding Interview Prep',
|
||||
// 'Project Euler'
|
||||
// ];
|
||||
const superBlocks = [
|
||||
'Responsive Web Design',
|
||||
'JavaScript Algorithms and Data Structures (Beta)',
|
||||
'Front End Development Libraries',
|
||||
'Data Visualization',
|
||||
'Relational Database',
|
||||
'Back End Development and APIs',
|
||||
'Quality Assurance',
|
||||
'Scientific Computing with Python (Beta)',
|
||||
'Data Analysis with Python',
|
||||
'Information Security',
|
||||
'Machine Learning with Python',
|
||||
'College Algebra with Python',
|
||||
'A2 English for Developers (Beta)',
|
||||
'Foundational C# with Microsoft',
|
||||
'The Odin Project (Beta)',
|
||||
'Coding Interview Prep',
|
||||
'Project Euler',
|
||||
'Rosetta Code',
|
||||
'Legacy Responsive Web Design Challenges',
|
||||
'JavaScript Algorithms and Data Structures',
|
||||
'Legacy Python for Everybody'
|
||||
];
|
||||
|
||||
test.beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
@@ -56,20 +62,20 @@ test('the page should have all static data correctly placed', async () => {
|
||||
}
|
||||
});
|
||||
|
||||
// Enable this again after we release the 4 new superblocks
|
||||
// test('the page renders all curriculum certifications', async () => {
|
||||
// const curriculumBtns = page.getByTestId('curriculum-map-button');
|
||||
// await expect(curriculumBtns).toHaveCount(15);
|
||||
// for (let i = 0; i < superBlocks.length; i++) {
|
||||
// const btn = curriculumBtns.nth(i);
|
||||
// await expect(btn).toContainText(superBlocks[i]);
|
||||
// }
|
||||
// });
|
||||
test('the page renders all curriculum certifications', async () => {
|
||||
const curriculumBtns = page.getByTestId('curriculum-map-button');
|
||||
await expect(curriculumBtns).toHaveCount(superBlocks.length);
|
||||
for (let i = 0; i < superBlocks.length; i++) {
|
||||
const btn = curriculumBtns.nth(i);
|
||||
await expect(btn).toContainText(superBlocks[i]);
|
||||
}
|
||||
});
|
||||
|
||||
test.describe('Learn (authenticated user)', () => {
|
||||
test.use({ storageState: 'playwright/.auth/certified-user.json' });
|
||||
|
||||
test('the page shows a random quote for an authenticated user', async () => {
|
||||
await page.goto('/learn');
|
||||
const shownQuote = await page.getByTestId('random-quote').textContent();
|
||||
|
||||
const shownAuthorText = await page
|
||||
|
||||
+23
-5
@@ -15,10 +15,22 @@ const superBlocksWithLinks = [
|
||||
...superBlockOrder[SuperBlockStages.FrontEnd],
|
||||
...superBlockOrder[SuperBlockStages.Backend],
|
||||
...superBlockOrder[SuperBlockStages.Python],
|
||||
...superBlockOrder[SuperBlockStages.English],
|
||||
...superBlockOrder[SuperBlockStages.Professional],
|
||||
...superBlockOrder[SuperBlockStages.Extra]
|
||||
...superBlockOrder[SuperBlockStages.Extra],
|
||||
...superBlockOrder[SuperBlockStages.Legacy]
|
||||
];
|
||||
|
||||
const superBlockTitleOverride: Record<string, string> = {
|
||||
'Responsive Web Design': 'Legacy Responsive Web Design Challenges',
|
||||
'JavaScript Algorithms and Data Structures':
|
||||
'JavaScript Algorithms and Data Structures Certification'
|
||||
};
|
||||
|
||||
const superBlockSlugOverride: Record<string, string> = {
|
||||
'2022/responsive-web-design': 'responsive-web-design'
|
||||
};
|
||||
|
||||
test.describe('Map Component', () => {
|
||||
test('should render correctly', async ({ page }) => {
|
||||
await expect(
|
||||
@@ -30,14 +42,20 @@ test.describe('Map Component', () => {
|
||||
await expect(
|
||||
page.getByText(translations.landing['interview-prep-heading'])
|
||||
).toBeVisible();
|
||||
// const curriculumBtns = page.getByTestId('curriculum-map-button');
|
||||
// await expect(curriculumBtns).toHaveCount(15);
|
||||
const curriculumBtns = page.getByTestId('curriculum-map-button');
|
||||
await expect(curriculumBtns).toHaveCount(superBlocksWithLinks.length);
|
||||
for (let i = 0; i < superBlocksWithLinks.length; i++) {
|
||||
const superblockLink = page.getByRole('link', {
|
||||
name: intro[superBlocksWithLinks[i]].title
|
||||
// This is a hacky bypass because `Responsive Web Design` hits both links.
|
||||
name:
|
||||
superBlockTitleOverride[intro[superBlocksWithLinks[i]].title] ??
|
||||
intro[superBlocksWithLinks[i]].title
|
||||
});
|
||||
expect(await superblockLink.getAttribute('href')).toBe(
|
||||
`/learn/${superBlocksWithLinks[i]}/`
|
||||
`/learn/${
|
||||
superBlockSlugOverride[superBlocksWithLinks[i]] ??
|
||||
superBlocksWithLinks[i]
|
||||
}/`
|
||||
);
|
||||
await superblockLink.click();
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto(
|
||||
'/learn/scientific-computing-with-python/python-for-everybody/introduction-why-program'
|
||||
'/learn/python-for-everybody/python-for-everybody/introduction-why-program'
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
+1
-2
@@ -36,6 +36,5 @@
|
||||
"automerge": false
|
||||
}
|
||||
],
|
||||
"ignorePaths": ["api-server"],
|
||||
"schedule": ["every weekend"]
|
||||
"ignorePaths": ["api-server"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user