feat(test, e2e) test suit for cypress (#42138)
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
@ -1,41 +0,0 @@
|
||||
/* global cy */
|
||||
|
||||
const locations = {
|
||||
index:
|
||||
'learn/apis-and-microservices/managing-packages-with-npm/' +
|
||||
'how-to-use-package-json-the-core-of-any-node-js-project-or-npm-package'
|
||||
};
|
||||
|
||||
const selectors = {
|
||||
defaultOutput: '.output-text',
|
||||
input: 'input[name="solution"]'
|
||||
};
|
||||
|
||||
const unhandledErrorMessage = 'Something is not quite right';
|
||||
const runningOutput = '// running tests';
|
||||
const finishedOutput = '// tests completed';
|
||||
|
||||
describe('Backend challenge', function () {
|
||||
it('renders', () => {
|
||||
cy.visit(locations.index);
|
||||
|
||||
cy.title().should(
|
||||
'eq',
|
||||
'Managing Packages with Npm - How to Use package.json, the Core of Any' +
|
||||
' Node.js Project or npm Package | Learn | freeCodeCamp.org'
|
||||
);
|
||||
});
|
||||
|
||||
it('does not generate unhandled errors on submission', () => {
|
||||
cy.visit(locations.index);
|
||||
cy.get(selectors.input)
|
||||
.type('https://example.com')
|
||||
.type('{enter}')
|
||||
.then(() => {
|
||||
cy.get(selectors.defaultOutput)
|
||||
.contains(runningOutput)
|
||||
.contains(finishedOutput);
|
||||
cy.contains(unhandledErrorMessage).should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
@ -1,64 +0,0 @@
|
||||
/* global cy */
|
||||
|
||||
const selectors = {
|
||||
defaultOutput: '.output-text',
|
||||
editor: '.monaco-editor',
|
||||
hotkeys: '.default-layout > div',
|
||||
runTestsButton: 'button:contains("Run the Tests")'
|
||||
};
|
||||
|
||||
const locations = {
|
||||
index:
|
||||
'/learn/responsive-web-design/basic-html-and-html5/' +
|
||||
'say-hello-to-html-elements'
|
||||
};
|
||||
|
||||
const defaultOutput = `
|
||||
/**
|
||||
* Your test output will go here
|
||||
*/`;
|
||||
|
||||
const runningOutput = '// running tests';
|
||||
const finishedOutput = '// tests completed';
|
||||
|
||||
describe('Classic challenge', function () {
|
||||
before(() => {
|
||||
cy.visit(locations.index);
|
||||
});
|
||||
|
||||
it('renders the default output text', () => {
|
||||
cy.title().should(
|
||||
'eq',
|
||||
'Learn Basic HTML and HTML5: Say Hello to HTML Elements |' +
|
||||
' freeCodeCamp.org'
|
||||
);
|
||||
cy.get(selectors.defaultOutput).contains(defaultOutput);
|
||||
});
|
||||
|
||||
it('shows test output when the tests are run', () => {
|
||||
// first wait for the editor to load
|
||||
cy.get(selectors.editor, { timeout: 15000 });
|
||||
cy.get(selectors.runTestsButton)
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.get(selectors.defaultOutput)
|
||||
.contains(runningOutput)
|
||||
.contains(finishedOutput);
|
||||
});
|
||||
});
|
||||
|
||||
it('shows test output when the tests are triggered by the keyboard', () => {
|
||||
// first wait for the editor to load
|
||||
cy.get(selectors.editor, {
|
||||
timeout: 15000
|
||||
});
|
||||
cy.get(selectors.hotkeys)
|
||||
.focus()
|
||||
.type('{ctrl}{enter}')
|
||||
.then(() => {
|
||||
cy.get(selectors.defaultOutput)
|
||||
.contains(runningOutput)
|
||||
.contains(finishedOutput);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,52 +0,0 @@
|
||||
/* global cy */
|
||||
|
||||
const projects = {
|
||||
superBlock: 'machine-learning-with-python',
|
||||
block: 'machine-learning-with-python-projects',
|
||||
challenges: [
|
||||
{
|
||||
slug: 'book-recommendation-engine-using-knn',
|
||||
nextChallengeText: 'Linear Regression Health Costs Calculator'
|
||||
},
|
||||
{
|
||||
slug: 'cat-and-dog-image-classifier',
|
||||
nextChallengeText: 'Book Recommendation Engine using KNN'
|
||||
},
|
||||
{
|
||||
slug: 'linear-regression-health-costs-calculator',
|
||||
nextChallengeText: 'Neural Network SMS Text Classifier'
|
||||
},
|
||||
{
|
||||
slug: 'neural-network-sms-text-classifier',
|
||||
nextChallengeText: 'Find the Symmetric Difference'
|
||||
},
|
||||
{
|
||||
slug: 'rock-paper-scissors',
|
||||
nextChallengeText: 'Cat and Dog Image Classifier'
|
||||
}
|
||||
]
|
||||
};
|
||||
describe('project submission', () => {
|
||||
// NOTE: this will fail once challenge tests are added.
|
||||
it('Should be possible to submit Python projects', () => {
|
||||
const { superBlock, block, challenges } = projects;
|
||||
challenges.forEach(({ slug }) => {
|
||||
const url = `/learn/${superBlock}/${block}/${slug}`;
|
||||
cy.visit(url);
|
||||
cy.get('#dynamic-front-end-form')
|
||||
.get('#solution')
|
||||
.type('https://replit.com/@camperbot/python-project#main.py');
|
||||
|
||||
cy.contains("I've completed this challenge").click();
|
||||
cy.contains('Go to next challenge');
|
||||
// clicking on 'Go to next challenge' seems to have caused flakiness, so
|
||||
// it's commented out until we figure out why.
|
||||
// cy.contains('Go to next challenge').click();
|
||||
|
||||
// The next two commands are to confirm that go to next challenge has
|
||||
// moved us to the expected challenge before we loop again.
|
||||
// cy.get('.title-text').should('include.text', nextChallengeText);
|
||||
// cy.url().should('not.have.string', url);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,19 +0,0 @@
|
||||
/* global cy */
|
||||
|
||||
describe('Certification intro page', () => {
|
||||
before(() => {
|
||||
cy.clearCookies();
|
||||
cy.login();
|
||||
cy.visit('/learn/coding-interview-prep');
|
||||
});
|
||||
|
||||
it('Should render', () => {
|
||||
cy.contains(
|
||||
"If you're looking for free coding exercises to prepare for your next job interview, we've got you covered."
|
||||
).should('be.visible');
|
||||
});
|
||||
|
||||
it('Title should not include the word "Certification"', () => {
|
||||
cy.title().should('eq', 'Coding Interview Prep | freeCodeCamp.org');
|
||||
});
|
||||
});
|
@ -1,31 +0,0 @@
|
||||
/* global cy */
|
||||
|
||||
const selectors = {
|
||||
footer: '.site-footer'
|
||||
};
|
||||
|
||||
describe('Footer', () => {
|
||||
it('Should render on landing page', () => {
|
||||
cy.visit('/');
|
||||
cy.get(selectors.footer).should('be.visible');
|
||||
});
|
||||
|
||||
it('Should render on learn page', () => {
|
||||
cy.visit('/learn');
|
||||
cy.get(selectors.footer).should('be.visible');
|
||||
cy.visit('/learn/');
|
||||
cy.get(selectors.footer).should('be.visible');
|
||||
});
|
||||
|
||||
it('Should render on superblock page', () => {
|
||||
cy.visit('/learn/responsive-web-design/');
|
||||
cy.get(selectors.footer).should('be.visible');
|
||||
});
|
||||
|
||||
it('Should not render on challenge page', () => {
|
||||
cy.visit(
|
||||
'/learn/responsive-web-design/basic-html-and-html5/say-hello-to-html-elements'
|
||||
);
|
||||
cy.get(selectors.footer).should('not.exist');
|
||||
});
|
||||
});
|
@ -1,36 +0,0 @@
|
||||
/* global cy */
|
||||
|
||||
describe('Help Button', () => {
|
||||
it('should be visible', () => {
|
||||
cy.visit(
|
||||
'/learn/responsive-web-design/basic-html-and-html5/say-hello-to-html-elements'
|
||||
);
|
||||
cy.get('#get-help-dropdown').scrollIntoView().should('be.visible');
|
||||
});
|
||||
|
||||
it('should toggle the dropdown menu', () => {
|
||||
cy.get('#get-help-dropdown').scrollIntoView().click();
|
||||
cy.get('ul[role="menu"]').should('be.visible');
|
||||
});
|
||||
|
||||
it('should render three links when video is available', () => {
|
||||
cy.get('ul[role="menu"]').within(() => {
|
||||
cy.get('a').should('have.length', 3);
|
||||
cy.get('a').eq(0).contains('Get a Hint');
|
||||
cy.get('a').eq(1).contains('Watch a Video');
|
||||
cy.get('a').eq(2).contains('Ask for Help');
|
||||
});
|
||||
});
|
||||
|
||||
it('should render two links when video is not available', () => {
|
||||
cy.visit(
|
||||
'/learn/front-end-libraries/bootstrap/apply-the-default-bootstrap-button-style'
|
||||
);
|
||||
cy.get('#get-help-dropdown').scrollIntoView().click();
|
||||
cy.get('ul[role="menu"]').within(() => {
|
||||
cy.get('a').should('have.length', 2);
|
||||
cy.get('a').eq(0).contains('Get a Hint');
|
||||
cy.get('a').eq(1).contains('Ask for Help');
|
||||
});
|
||||
});
|
||||
});
|
@ -1,109 +0,0 @@
|
||||
/* global cy */
|
||||
|
||||
const selectors = {
|
||||
heading: "[data-test-label='landing-header']",
|
||||
smallCallToAction: "[data-test-label='landing-small-cta']",
|
||||
navigationLinks: '.nav-list',
|
||||
avatarContainer: '.avatar-container',
|
||||
defaultAvatar: '.avatar-container',
|
||||
menuButton: '.toggle-button-nav',
|
||||
avatarImage: '.avatar-container .avatar'
|
||||
};
|
||||
|
||||
let appHasStarted;
|
||||
function spyOnListener(win) {
|
||||
const addListener = win.EventTarget.prototype.addEventListener;
|
||||
win.EventTarget.prototype.addEventListener = function (name) {
|
||||
if (name === 'click') {
|
||||
appHasStarted = true;
|
||||
win.EventTarget.prototype.addEventListener = addListener;
|
||||
}
|
||||
return addListener.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
function waitForAppStart() {
|
||||
return new Promise(resolve => {
|
||||
const isReady = () => {
|
||||
if (appHasStarted) {
|
||||
return resolve();
|
||||
}
|
||||
return setTimeout(isReady, 0);
|
||||
};
|
||||
isReady();
|
||||
});
|
||||
}
|
||||
|
||||
describe('Navbar', () => {
|
||||
beforeEach(() => {
|
||||
appHasStarted = false;
|
||||
cy.visit('/', {
|
||||
onBeforeLoad: spyOnListener
|
||||
}).then(waitForAppStart);
|
||||
cy.viewport(1300, 660);
|
||||
});
|
||||
|
||||
it('Should render properly', () => {
|
||||
cy.get('#universal-nav').should('be.visible');
|
||||
cy.get('#universal-nav').should('have.class', 'universal-nav');
|
||||
});
|
||||
|
||||
it(
|
||||
'Should take user to learn page when clicked on ' + 'the freeCodeCamp logo',
|
||||
() => {
|
||||
cy.get('.universal-nav-middle').within(() => {
|
||||
cy.get('svg').click();
|
||||
});
|
||||
cy.url().should('include', '/learn');
|
||||
}
|
||||
);
|
||||
|
||||
it('Should have a "Sign in" button', () => {
|
||||
cy.contains("[data-test-label='landing-small-cta']", 'Sign in');
|
||||
});
|
||||
|
||||
// have the curriculum and CTA on landing and /learn pages.
|
||||
it(
|
||||
'Should have `Radio`, `Forum`, and `Curriculum` links on landing and learn pages' +
|
||||
'page when not signed in',
|
||||
() => {
|
||||
cy.get(selectors.menuButton).click();
|
||||
cy.get(selectors.navigationLinks).contains('Forum');
|
||||
cy.get(selectors.navigationLinks).contains('Curriculum').click();
|
||||
cy.url().should('include', '/learn');
|
||||
cy.get(selectors.navigationLinks).contains('Curriculum');
|
||||
cy.get(selectors.navigationLinks).contains('Forum');
|
||||
cy.get(selectors.navigationLinks).contains('Radio');
|
||||
}
|
||||
);
|
||||
|
||||
it(
|
||||
'Should have `Sign in` link on landing and learn pages' +
|
||||
' when not signed in',
|
||||
() => {
|
||||
cy.contains(selectors.smallCallToAction, 'Sign in');
|
||||
cy.get(selectors.menuButton).click();
|
||||
cy.get(selectors.navigationLinks).contains('Curriculum').click();
|
||||
cy.contains(selectors.smallCallToAction, 'Sign in');
|
||||
}
|
||||
);
|
||||
|
||||
it('Should have `Profile` link when user is signed in', () => {
|
||||
cy.login();
|
||||
cy.get(selectors.menuButton).click();
|
||||
cy.get(selectors.navigationLinks).contains('Profile').click();
|
||||
cy.url().should('include', '/developmentuser');
|
||||
});
|
||||
|
||||
it('Should have a profile image with class `default-border`', () => {
|
||||
cy.login();
|
||||
cy.get(selectors.avatarContainer).should('have.class', 'default-border');
|
||||
cy.get(selectors.defaultAvatar).should('exist');
|
||||
});
|
||||
|
||||
it('Should have a profile image with dimensions that are <= 31px', () => {
|
||||
cy.login();
|
||||
cy.get(selectors.avatarImage).invoke('width').should('lte', 31);
|
||||
cy.get(selectors.avatarImage).invoke('height').should('lte', 31);
|
||||
});
|
||||
});
|
@ -1,77 +0,0 @@
|
||||
/* global cy */
|
||||
|
||||
const search = query => {
|
||||
cy.get('.ais-SearchBox').within(() => {
|
||||
cy.get('input').type(query);
|
||||
});
|
||||
|
||||
cy.wait(300);
|
||||
};
|
||||
|
||||
const clear = () => {
|
||||
cy.get('.ais-SearchBox').within(() => {
|
||||
cy.get('input').clear();
|
||||
});
|
||||
};
|
||||
|
||||
describe('Search bar', () => {
|
||||
before(() => {
|
||||
cy.visit('/');
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
clear();
|
||||
});
|
||||
|
||||
it('Should render properly', () => {
|
||||
cy.get('.ais-SearchBox').should('be.visible');
|
||||
});
|
||||
|
||||
it('Should accept input and display hits', () => {
|
||||
search('freeCodeCamp');
|
||||
|
||||
cy.get('.ais-Hits-list').children().should('to.have.length.of.at.least', 1);
|
||||
});
|
||||
|
||||
it('Should clear hits when input is cleared', () => {
|
||||
search('freeCodeCamp');
|
||||
|
||||
cy.get('.ais-Hits-list').children().should('to.have.length.of.at.least', 1);
|
||||
|
||||
clear();
|
||||
|
||||
cy.get('div.ais-Hits').should('not.exist');
|
||||
});
|
||||
|
||||
it('Should show up to 8 hits when height >= 768px', () => {
|
||||
cy.viewport(1300, 768);
|
||||
|
||||
search('freeCodeCamp');
|
||||
|
||||
cy.get('.ais-Hits-list').children().should('to.have.length.of', 8);
|
||||
});
|
||||
|
||||
it('Should show up to 5 hits when height < 768px', () => {
|
||||
cy.viewport(1300, 767);
|
||||
|
||||
search('freeCodeCamp');
|
||||
|
||||
cy.get('.ais-Hits-list').children().should('to.have.length.of', 5);
|
||||
});
|
||||
|
||||
it('Should show no hits for queries that do not exist in the Algolia index', () => {
|
||||
search('testtttt');
|
||||
|
||||
cy.get('.ais-Hits-list').children().should('to.have.length.of', 0);
|
||||
|
||||
cy.contains('No tutorials found');
|
||||
});
|
||||
|
||||
it('Should not redirect to the News search page if there are no hits', () => {
|
||||
search('testtttt');
|
||||
|
||||
cy.get('.ais-SearchBox-form').submit();
|
||||
|
||||
cy.url('/');
|
||||
});
|
||||
});
|
@ -1,65 +0,0 @@
|
||||
/* global cy */
|
||||
|
||||
const selectors = {
|
||||
donateSupport: {
|
||||
firstTitle: '.donate-support h4:first-of-type b',
|
||||
secondTitle: '.donate-support h4:last-of-type b',
|
||||
firstText: '.donate-support p:first-of-type',
|
||||
secondText: '.donate-support p:last-of-type',
|
||||
link: '.donate-support a'
|
||||
}
|
||||
};
|
||||
|
||||
describe('Donate page', () => {
|
||||
before(() => {
|
||||
cy.clearCookies();
|
||||
cy.exec('npm run seed');
|
||||
cy.login();
|
||||
cy.visit('/donate');
|
||||
});
|
||||
|
||||
it('Should render', () => {
|
||||
cy.title().should('eq', 'Support our nonprofit | freeCodeCamp.org');
|
||||
});
|
||||
|
||||
it('Should display default amount and duration', () => {
|
||||
cy.contains('Confirm your donation of $5 / month:').should('be.visible');
|
||||
});
|
||||
|
||||
it('Should have support section', () => {
|
||||
cy.contains(
|
||||
'Want to make a bigger one-time donation, mail us a check, or give in other ways?'
|
||||
).should('be.visible');
|
||||
});
|
||||
|
||||
it('Support section should have support text', () => {
|
||||
cy.contains(
|
||||
selectors.donateSupport.firstTitle,
|
||||
'Want to make a bigger one-time donation, mail us a check, or give in other ways?'
|
||||
);
|
||||
cy.contains(
|
||||
selectors.donateSupport.secondTitle,
|
||||
'Need help with your current or past donations?'
|
||||
);
|
||||
cy.contains(
|
||||
selectors.donateSupport.firstText,
|
||||
"Here are many other ways you can support our non-profit's mission."
|
||||
);
|
||||
cy.contains(
|
||||
selectors.donateSupport.secondText,
|
||||
'Forward a copy of your donation receipt to donors@freecodecamp.org and tell us how we can help.'
|
||||
);
|
||||
});
|
||||
|
||||
it('Support section should have donation link', () => {
|
||||
cy.get(selectors.donateSupport.link).should(
|
||||
'have.attr',
|
||||
'href',
|
||||
'https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp'
|
||||
);
|
||||
});
|
||||
|
||||
it('Donor alert should not be visible for non-donor', () => {
|
||||
cy.get('.alert-info').should('not.exist');
|
||||
});
|
||||
});
|
@ -1,45 +0,0 @@
|
||||
/* global cy */
|
||||
|
||||
const selectors = {
|
||||
donateAlert: {
|
||||
firstText: '.alert-info p:first-child',
|
||||
secondText: '.alert-info p:last-child',
|
||||
link: '.alert-info a'
|
||||
}
|
||||
};
|
||||
|
||||
describe('Donate page', () => {
|
||||
before(() => {
|
||||
cy.clearCookies();
|
||||
cy.exec('npm run seed -- --donor');
|
||||
cy.login();
|
||||
cy.visit('/donate');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.exec('npm run seed');
|
||||
});
|
||||
|
||||
it('Donor alert should be visible for donor', () => {
|
||||
cy.get('.alert-info').should('be.visible');
|
||||
});
|
||||
|
||||
it('Donor should see alert message', () => {
|
||||
cy.contains(
|
||||
selectors.donateAlert.firstText,
|
||||
'Thank you for being a supporter of freeCodeCamp. You currently have a recurring donation.'
|
||||
);
|
||||
cy.contains(
|
||||
selectors.donateAlert.lastText,
|
||||
"Want to make a bigger one-time donation, mail us a check, or give in other ways? Here are many other ways you can support our non-profit's mission."
|
||||
);
|
||||
});
|
||||
|
||||
it('Donor alert section should have donation link', () => {
|
||||
cy.get(selectors.donateAlert.link).should(
|
||||
'have.attr',
|
||||
'href',
|
||||
'https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp'
|
||||
);
|
||||
});
|
||||
});
|
@ -1,45 +0,0 @@
|
||||
/* global cy */
|
||||
|
||||
describe('Donate page', () => {
|
||||
before(() => {
|
||||
cy.clearCookies();
|
||||
cy.exec('npm run seed');
|
||||
cy.login();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.exec('npm run seed');
|
||||
});
|
||||
|
||||
const projects = [
|
||||
'tribute-page',
|
||||
'survey-form',
|
||||
'product-landing-page',
|
||||
'technical-documentation-page',
|
||||
'personal-portfolio-webpage'
|
||||
];
|
||||
|
||||
it('Should be able to submit projects', () => {
|
||||
const submitProject = str => {
|
||||
cy.visit(
|
||||
`/learn/responsive-web-design/responsive-web-design-projects/build-a-${str}`
|
||||
);
|
||||
cy.get('#dynamic-front-end-form')
|
||||
.get('#solution')
|
||||
.type('https://codepen.io/camperbot/full/oNvPqqo', {
|
||||
force: true
|
||||
});
|
||||
|
||||
cy.contains("I've completed this challenge").click();
|
||||
cy.contains('Submit and go to next challenge').click();
|
||||
};
|
||||
|
||||
projects.forEach(project => submitProject(project));
|
||||
});
|
||||
|
||||
it('Should have a pop up modal', () => {
|
||||
cy.contains(
|
||||
'Nicely done. You just completed Responsive Web Design Projects.'
|
||||
);
|
||||
});
|
||||
});
|
@ -1,85 +0,0 @@
|
||||
/* global cy expect */
|
||||
|
||||
const selectors = {
|
||||
challengeMap: "[data-test-label='learn-curriculum-map']"
|
||||
};
|
||||
|
||||
const locations = {
|
||||
index: '/learn'
|
||||
};
|
||||
|
||||
const superBlockNames = [
|
||||
'Responsive Web Design Certification',
|
||||
'JavaScript Algorithms and Data Structures Certification',
|
||||
'Front End Development Libraries Certification',
|
||||
'Data Visualization Certification',
|
||||
'APIs and Microservices Certification',
|
||||
'Quality Assurance Certification',
|
||||
'Scientific Computing with Python Certification',
|
||||
'Data Analysis with Python Certification',
|
||||
'Information Security Certification',
|
||||
'Machine Learning with Python Certification',
|
||||
'Coding Interview Prep (Thousands of hours of challenges)'
|
||||
];
|
||||
|
||||
describe('Learn Landing page (not logged in)', () => {
|
||||
it('Should render', () => {
|
||||
cy.visit(locations.index);
|
||||
|
||||
cy.title().should(
|
||||
'eq',
|
||||
'Learn to Code — For Free — Coding Courses for Busy People'
|
||||
);
|
||||
});
|
||||
|
||||
it('Has the correct heading for an unauthenticated User', () => {
|
||||
cy.visit(locations.index);
|
||||
|
||||
cy.contains('h1', "Welcome to freeCodeCamp's curriculum.");
|
||||
});
|
||||
|
||||
it('Should render a curriculum map', () => {
|
||||
cy.document().then(document => {
|
||||
const superBlocks = document.querySelectorAll(
|
||||
`${selectors.challengeMap} > li > a`
|
||||
);
|
||||
expect(superBlocks).to.have.length(11);
|
||||
|
||||
superBlocks.forEach((superBlock, idx) => {
|
||||
expect(superBlock.innerText).to.have.string(superBlockNames[idx]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Quotes', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/');
|
||||
cy.contains("Get started (it's free)").click();
|
||||
});
|
||||
|
||||
it('Should show a quote', () => {
|
||||
cy.get('blockquote').within(() => {
|
||||
cy.get('q').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should show quote author', () => {
|
||||
cy.get('blockquote').within(() => {
|
||||
cy.get('cite').should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Superblocks and Blocks', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/');
|
||||
cy.contains("Get started (it's free)").click();
|
||||
});
|
||||
|
||||
it('Has all superblocks visible', () => {
|
||||
cy.wrap(superBlockNames.slice(1)).each(name => {
|
||||
cy.contains(name).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
@ -1,54 +0,0 @@
|
||||
/* global cy expect */
|
||||
|
||||
const locations = {
|
||||
chalSuper: '/challenges/responsive-web-design/',
|
||||
chalBlock: '/challenges/responsive-web-design/basic-html-and-html5',
|
||||
chalChallenge:
|
||||
// eslint-disable-next-line max-len
|
||||
'/challenges/responsive-web-design/basic-html-and-html5/say-hello-to-html-elements',
|
||||
learnSuper: '/learn/responsive-web-design',
|
||||
learnBlock: '/learn/responsive-web-design/basic-html-and-html5',
|
||||
learnChallenge:
|
||||
// eslint-disable-next-line max-len
|
||||
'/learn/responsive-web-design/basic-html-and-html5/say-hello-to-html-elements'
|
||||
};
|
||||
|
||||
describe('challenges/superblock redirect', function () {
|
||||
it('redirects to learn/superblock', () => {
|
||||
cy.visit(locations.chalSuper);
|
||||
|
||||
cy.title().should(
|
||||
'eq',
|
||||
'Responsive Web Design Certification | freeCodeCamp.org'
|
||||
);
|
||||
cy.location().should(loc => {
|
||||
expect(loc.pathname).to.eq(locations.learnSuper);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('challenges/superblock/block redirect', function () {
|
||||
it('redirects to learn/superblock/block', () => {
|
||||
cy.visit(locations.chalBlock);
|
||||
|
||||
cy.title().should('eq', 'Basic HTML and HTML5 | freeCodeCamp.org');
|
||||
cy.location().should(loc => {
|
||||
expect(loc.pathname).to.eq(locations.learnBlock);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('challenges/superblock/block/challenge redirect', function () {
|
||||
it('redirects to learn/superblock/block/challenge', () => {
|
||||
cy.visit(locations.chalChallenge);
|
||||
|
||||
cy.title().should(
|
||||
'eq',
|
||||
// eslint-disable-next-line max-len
|
||||
'Learn Basic HTML and HTML5: Say Hello to HTML Elements | freeCodeCamp.org'
|
||||
);
|
||||
cy.location().should(loc => {
|
||||
expect(loc.pathname).to.eq(locations.learnChallenge);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,81 +0,0 @@
|
||||
/* global cy */
|
||||
|
||||
const selectors = {
|
||||
tableOfContents: '.intro-toc',
|
||||
warningMessage: '.flash-message-enter-active'
|
||||
};
|
||||
|
||||
const locations = {
|
||||
index: '/learn/responsive-web-design/basic-css/'
|
||||
};
|
||||
|
||||
const lessonNames = [
|
||||
'Change the Color of Text',
|
||||
'Use CSS Selectors to Style Elements',
|
||||
'Use a CSS Class to Style an Element',
|
||||
'Style Multiple Elements with a CSS Class',
|
||||
'Change the Font Size of an Element',
|
||||
'Set the Font Family of an Element',
|
||||
'Import a Google Font',
|
||||
'Specify How Fonts Should Degrade',
|
||||
'Size Your Images',
|
||||
'Add Borders Around Your Elements',
|
||||
'Add Rounded Corners with border-radius',
|
||||
'Make Circular Images with a border-radius',
|
||||
'Give a Background Color to a div Element',
|
||||
'Set the id of an Element',
|
||||
'Use an id Attribute to Style an Element',
|
||||
'Adjust the Padding of an Element',
|
||||
'Adjust the Margin of an Element',
|
||||
'Add a Negative Margin to an Element',
|
||||
'Add Different Padding to Each Side of an Element',
|
||||
'Add Different Margins to Each Side of an Element',
|
||||
'Use Clockwise Notation to Specify the Padding of an Element',
|
||||
'Use Clockwise Notation to Specify the Margin of an Element',
|
||||
'Use Attribute Selectors to Style Elements',
|
||||
'Understand Absolute versus Relative Units',
|
||||
'Style the HTML Body Element',
|
||||
'Inherit Styles from the Body Element',
|
||||
'Prioritize One Style Over Another',
|
||||
'Override Styles in Subsequent CSS',
|
||||
'Override Class Declarations by Styling ID Attributes',
|
||||
'Override Class Declarations with Inline Styles',
|
||||
'Override All Other Styles by using Important',
|
||||
'Use Hex Code for Specific Colors',
|
||||
'Use Hex Code to Mix Colors',
|
||||
'Use Abbreviated Hex Code',
|
||||
'Use RGB values to Color Elements',
|
||||
'Use RGB to Mix Colors',
|
||||
'Use CSS Variables to change several elements at once',
|
||||
'Create a custom CSS Variable',
|
||||
'Use a custom CSS Variable',
|
||||
'Attach a Fallback value to a CSS Variable',
|
||||
'Improve Compatibility with Browser Fallbacks',
|
||||
'Inherit CSS Variables',
|
||||
'Change a variable for a specific area',
|
||||
'Use a media query to change a variable'
|
||||
];
|
||||
|
||||
const warningMessage =
|
||||
'Note: Some browser extensions may interfere with elements on the page. ' +
|
||||
'If the tests fail, try disabling your extensions for the most reliable ' +
|
||||
'experience.';
|
||||
|
||||
describe('Basic Css Introduction page', function () {
|
||||
it('renders', () => {
|
||||
cy.visit(locations.index);
|
||||
|
||||
cy.title().should('eq', 'Basic CSS | freeCodeCamp.org');
|
||||
});
|
||||
|
||||
it('renders a warning user about extensions', () => {
|
||||
cy.visit(locations.index);
|
||||
cy.get(selectors.warningMessage).contains(warningMessage);
|
||||
});
|
||||
|
||||
it('renders a lesson index', () => {
|
||||
lessonNames.forEach(name => {
|
||||
cy.get(selectors.tableOfContents).contains('span', name);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,41 +0,0 @@
|
||||
/* global cy */
|
||||
|
||||
const selectors = {
|
||||
firstBlock: '.block-ui > .block:nth-child(1) > .map-title'
|
||||
};
|
||||
|
||||
describe('Certification intro page', () => {
|
||||
before(() => {
|
||||
cy.clearCookies();
|
||||
cy.login();
|
||||
cy.visit('/learn/responsive-web-design');
|
||||
});
|
||||
|
||||
it('Should render', () => {
|
||||
cy.title().should(
|
||||
'eq',
|
||||
'Responsive Web Design Certification | freeCodeCamp.org'
|
||||
);
|
||||
});
|
||||
|
||||
it('Should have certification intro text', () => {
|
||||
cy.contains(
|
||||
"In this Responsive Web Design Certification, you'll learn the languages that developers use to build webpages"
|
||||
).should('be.visible');
|
||||
});
|
||||
|
||||
it('First block should be expanded', () => {
|
||||
cy.contains('Say Hello to HTML Elements').should('be.visible');
|
||||
});
|
||||
|
||||
it('Second block should be closed', () => {
|
||||
cy.contains('Change the Color of Text').should('not.exist');
|
||||
});
|
||||
|
||||
it('Block should handle toggle clicks correctly', () => {
|
||||
cy.get(selectors.firstBlock).click();
|
||||
cy.contains('Say Hello to HTML Elements').should('not.exist');
|
||||
cy.get(selectors.firstBlock).click();
|
||||
cy.contains('Say Hello to HTML Elements').should('be.visible');
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user