From 8d123769315cf5e87fa31d22881dfe1430c6b63c Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Thu, 29 Jun 2023 18:18:10 +0200 Subject: [PATCH] chore(cypress): speed up seeding when testing (#50825) --- cypress.config.js | 7 ++++ .../e2e/default/learn/challenges/codeally.ts | 4 +-- .../learn/challenges/failed-updates.ts | 2 +- .../challenges/multifile-cert-project.ts | 4 +-- .../default/learn/challenges/navigation.ts | 2 +- .../default/learn/challenges/progress-bar.ts | 2 +- .../e2e/default/learn/challenges/projects.ts | 2 +- .../default/learn/donate/donate-page-donor.ts | 2 +- .../donate/donation-block-completion-modal.ts | 4 +-- .../learn/header/universal-navigation.ts | 6 ++-- .../learn/responsive-web-design/intro-page.ts | 2 +- .../show-cert-from-superblock.ts | 4 +-- .../e2e/default/settings/certifications.ts | 4 +-- cypress/e2e/default/settings/email-change.ts | 2 +- cypress/e2e/default/settings/user-token.ts | 4 +-- cypress/e2e/default/show-certification.ts | 2 +- cypress/e2e/default/top-contributor.ts | 4 +-- cypress/e2e/default/user/certifications.ts | 2 +- cypress/e2e/default/user/privacy-terms.ts | 4 +-- cypress/e2e/default/user/report-user.ts | 2 +- cypress/e2e/third-party/donate-page.ts | 2 +- tools/scripts/seed/seed-demo-user.js | 33 +++++++++++++++---- 22 files changed, 63 insertions(+), 37 deletions(-) diff --git a/cypress.config.js b/cypress.config.js index 50ca8da6079..b424019708a 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -2,6 +2,10 @@ const { execSync } = require('child_process'); const { existsSync } = require('fs'); const { defineConfig } = require('cypress'); +function seed(args = []) { + return execSync('node tools/scripts/seed/seed-demo-user ' + args.join(' ')); +} + module.exports = defineConfig({ e2e: { baseUrl: 'http://localhost:8000', @@ -31,6 +35,9 @@ module.exports = defineConfig({ execSync('pnpm run build:curriculum'); } }); + on('task', { + seed + }); config.env.API_LOCATION = 'http://localhost:3000'; return config; diff --git a/cypress/e2e/default/learn/challenges/codeally.ts b/cypress/e2e/default/learn/challenges/codeally.ts index 8d286299ec1..50bdccbc839 100644 --- a/cypress/e2e/default/learn/challenges/codeally.ts +++ b/cypress/e2e/default/learn/challenges/codeally.ts @@ -1,7 +1,7 @@ describe('CodeAlly cert challenge', function () { describe('before completing the project', function () { before(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); cy.visit( '/learn/relational-database/build-a-celestial-bodies-database-project/build-a-celestial-bodies-database' @@ -19,7 +19,7 @@ describe('CodeAlly cert challenge', function () { describe('after completing the project', function () { before(() => { - cy.exec('pnpm run seed:certified-user'); + cy.task('seed', ['certified-user']); cy.login(); cy.visit( '/learn/relational-database/build-a-celestial-bodies-database-project/build-a-celestial-bodies-database' diff --git a/cypress/e2e/default/learn/challenges/failed-updates.ts b/cypress/e2e/default/learn/challenges/failed-updates.ts index 365ab748a29..0c9f67207e8 100644 --- a/cypress/e2e/default/learn/challenges/failed-updates.ts +++ b/cypress/e2e/default/learn/challenges/failed-updates.ts @@ -21,7 +21,7 @@ function getCompletedIds(completedChallenges: ChallengeData[]): string[] { describe('failed update flushing', function () { before(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); }); diff --git a/cypress/e2e/default/learn/challenges/multifile-cert-project.ts b/cypress/e2e/default/learn/challenges/multifile-cert-project.ts index dee2399c902..34227e5d4f2 100644 --- a/cypress/e2e/default/learn/challenges/multifile-cert-project.ts +++ b/cypress/e2e/default/learn/challenges/multifile-cert-project.ts @@ -10,7 +10,7 @@ const editorElements = { describe('multifileCertProjects', function () { before(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); }); @@ -39,7 +39,7 @@ describe('multifileCertProjects', function () { it('should save using ctrl+s hotkey and persist through navigation', function () { // since rapid clicks will cause the save requests to be ignored, we have to // purge the db: - cy.exec('pnpm run seed'); + cy.task('seed'); // and the redux store: cy.reload(); cy.get(editorElements.container).find(editorElements.editor).click(); diff --git a/cypress/e2e/default/learn/challenges/navigation.ts b/cypress/e2e/default/learn/challenges/navigation.ts index 7a5de059baf..778e3f13911 100644 --- a/cypress/e2e/default/learn/challenges/navigation.ts +++ b/cypress/e2e/default/learn/challenges/navigation.ts @@ -14,7 +14,7 @@ const challenge2 = { describe('submitting a challenge', () => { before(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); }); diff --git a/cypress/e2e/default/learn/challenges/progress-bar.ts b/cypress/e2e/default/learn/challenges/progress-bar.ts index e465e86dc44..95fb478a719 100644 --- a/cypress/e2e/default/learn/challenges/progress-bar.ts +++ b/cypress/e2e/default/learn/challenges/progress-bar.ts @@ -1,6 +1,6 @@ describe('progress bar', () => { beforeEach(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); }); diff --git a/cypress/e2e/default/learn/challenges/projects.ts b/cypress/e2e/default/learn/challenges/projects.ts index 0bb29017d16..5f01dc5df4a 100644 --- a/cypress/e2e/default/learn/challenges/projects.ts +++ b/cypress/e2e/default/learn/challenges/projects.ts @@ -64,7 +64,7 @@ const pythonProjects = { describe('project submission', () => { beforeEach(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); }); // NOTE: this will fail once challenge tests are added. diff --git a/cypress/e2e/default/learn/donate/donate-page-donor.ts b/cypress/e2e/default/learn/donate/donate-page-donor.ts index 4c521cae5a9..c241540c129 100644 --- a/cypress/e2e/default/learn/donate/donate-page-donor.ts +++ b/cypress/e2e/default/learn/donate/donate-page-donor.ts @@ -1,6 +1,6 @@ describe('Donate page', () => { beforeEach(() => { - cy.exec('pnpm run seed -- --donor'); + cy.task('seed', ['--donor']); cy.login(); }); diff --git a/cypress/e2e/default/learn/donate/donation-block-completion-modal.ts b/cypress/e2e/default/learn/donate/donation-block-completion-modal.ts index de855bcb522..d5b830928de 100644 --- a/cypress/e2e/default/learn/donate/donation-block-completion-modal.ts +++ b/cypress/e2e/default/learn/donate/donation-block-completion-modal.ts @@ -1,12 +1,12 @@ describe('Donate page', () => { before(() => { cy.clearCookies(); - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); }); after(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); }); const projects = [ diff --git a/cypress/e2e/default/learn/header/universal-navigation.ts b/cypress/e2e/default/learn/header/universal-navigation.ts index 1da7b552348..6a61487aaf1 100644 --- a/cypress/e2e/default/learn/header/universal-navigation.ts +++ b/cypress/e2e/default/learn/header/universal-navigation.ts @@ -46,7 +46,7 @@ describe('Default Navigation Menu', () => { describe('Authenticated Navigation Menu', () => { before(() => { cy.clearCookies(); - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); cy.get(navigationItems['toggle-button']).should('be.visible').click(); }); @@ -68,7 +68,7 @@ describe('Authenticated Navigation Menu', () => { describe('Authenticated User Sign Out', () => { before(() => { cy.clearCookies(); - cy.exec('pnpm run seed'); + cy.task('seed'); }); beforeEach(() => { cy.login(); @@ -94,7 +94,7 @@ describe('Authenticated User Sign Out', () => { describe('Donor Navigation Menu', () => { before(() => { cy.clearCookies(); - cy.exec('pnpm run seed -- --donor'); + cy.task('seed', ['--donor']); cy.login(); cy.visit('/donate'); }); diff --git a/cypress/e2e/default/learn/responsive-web-design/intro-page.ts b/cypress/e2e/default/learn/responsive-web-design/intro-page.ts index 04e196f3d3b..f9d6edcea53 100644 --- a/cypress/e2e/default/learn/responsive-web-design/intro-page.ts +++ b/cypress/e2e/default/learn/responsive-web-design/intro-page.ts @@ -4,7 +4,7 @@ const introPageSelectors = { describe('Certification intro page', () => { before(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); }); diff --git a/cypress/e2e/default/learn/responsive-web-design/show-cert-from-superblock.ts b/cypress/e2e/default/learn/responsive-web-design/show-cert-from-superblock.ts index 4d0a3a094a0..d806349f772 100644 --- a/cypress/e2e/default/learn/responsive-web-design/show-cert-from-superblock.ts +++ b/cypress/e2e/default/learn/responsive-web-design/show-cert-from-superblock.ts @@ -29,7 +29,7 @@ const projects = { describe('Front End Development Libraries Superblock', () => { before(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); cy.visit('/learn/front-end-development-libraries'); }); @@ -41,7 +41,7 @@ describe('Front End Development Libraries Superblock', () => { }); describe('After submitting all 5 projects', () => { before(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); cy.visit('/settings'); cy.setPrivacyTogglesToPublic(); diff --git a/cypress/e2e/default/settings/certifications.ts b/cypress/e2e/default/settings/certifications.ts index dce7283a07d..09baaf9388d 100644 --- a/cypress/e2e/default/settings/certifications.ts +++ b/cypress/e2e/default/settings/certifications.ts @@ -3,7 +3,7 @@ import '@testing-library/cypress/add-commands'; describe('Settings certifications area', () => { describe('initially', () => { before(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); }); @@ -23,7 +23,7 @@ describe('Settings certifications area', () => { describe('after isHonest', () => { before(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); }); diff --git a/cypress/e2e/default/settings/email-change.ts b/cypress/e2e/default/settings/email-change.ts index 0e0e5994eb0..0d499feee4a 100644 --- a/cypress/e2e/default/settings/email-change.ts +++ b/cypress/e2e/default/settings/email-change.ts @@ -1,6 +1,6 @@ describe('Email input field', () => { beforeEach(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); cy.visit('/settings'); }); diff --git a/cypress/e2e/default/settings/user-token.ts b/cypress/e2e/default/settings/user-token.ts index f54899d00d8..54e318d875d 100644 --- a/cypress/e2e/default/settings/user-token.ts +++ b/cypress/e2e/default/settings/user-token.ts @@ -1,7 +1,7 @@ describe('User token widget on settings page,', function () { describe('initially', function () { beforeEach(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); }); @@ -15,7 +15,7 @@ describe('User token widget on settings page,', function () { describe('after creating token', function () { beforeEach(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); cy.visit( '/learn/relational-database/learn-bash-by-building-a-boilerplate/build-a-boilerplate' diff --git a/cypress/e2e/default/show-certification.ts b/cypress/e2e/default/show-certification.ts index 508a4cc65bf..33d9718e00c 100644 --- a/cypress/e2e/default/show-certification.ts +++ b/cypress/e2e/default/show-certification.ts @@ -2,7 +2,7 @@ const certifiedUser = '/certification/certifieduser/responsive-web-design'; describe('A certification,', function () { before(() => { - cy.exec('pnpm run seed:certified-user'); + cy.task('seed', ['certified-user']); }); describe('while viewing your own,', function () { diff --git a/cypress/e2e/default/top-contributor.ts b/cypress/e2e/default/top-contributor.ts index 4e4e3ebca71..f41f5ec9c93 100644 --- a/cypress/e2e/default/top-contributor.ts +++ b/cypress/e2e/default/top-contributor.ts @@ -1,11 +1,11 @@ describe('Top contributor in user profile', () => { before(() => { cy.clearCookies(); - cy.exec('pnpm run seed -- --top-contributor'); + cy.task('seed', ['--top-contributor']); }); after(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); }); beforeEach(() => { diff --git a/cypress/e2e/default/user/certifications.ts b/cypress/e2e/default/user/certifications.ts index bab91d1ded4..d6744b67636 100644 --- a/cypress/e2e/default/user/certifications.ts +++ b/cypress/e2e/default/user/certifications.ts @@ -1,7 +1,7 @@ describe('Public profile certifications', () => { context('Signed in user viewing their own public profile', () => { before(() => { - cy.exec('pnpm run seed:certified-user'); + cy.task('seed', ['certified-user']); }); beforeEach(() => { diff --git a/cypress/e2e/default/user/privacy-terms.ts b/cypress/e2e/default/user/privacy-terms.ts index 07a553c4976..332c246a36c 100644 --- a/cypress/e2e/default/user/privacy-terms.ts +++ b/cypress/e2e/default/user/privacy-terms.ts @@ -8,7 +8,7 @@ describe('Privacy terms', () => { }).as('updatePrivacyTerms'); // Seed dev user with `acceptedPrivacyTerms` unset - cy.exec('pnpm run seed -- --unset-privacy-terms'); + cy.task('seed', ['--unset-privacy-terms']); // Go to the homepage and log in manually so we can assert the following: // 1. Redirection to /email-sign-up works properly // 2. The /update-privacy-terms has not been requested @@ -37,7 +37,7 @@ describe('Privacy terms', () => { }).as('updatePrivacyTerms'); // Seed dev user with `acceptedPrivacyTerms` unset - cy.exec('pnpm run seed -- --unset-privacy-terms'); + cy.task('seed', ['--unset-privacy-terms']); // Go to the homepage and log in manually so we can assert the following: // 1. Redirection to /email-sign-up works properly // 2. The /update-privacy-terms has not been requested diff --git a/cypress/e2e/default/user/report-user.ts b/cypress/e2e/default/user/report-user.ts index c905c8bc100..4fe68b6aabc 100644 --- a/cypress/e2e/default/user/report-user.ts +++ b/cypress/e2e/default/user/report-user.ts @@ -1,6 +1,6 @@ describe('Report User', () => { beforeEach(() => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); }); it('should be possible to report a user from their profile page', () => { diff --git a/cypress/e2e/third-party/donate-page.ts b/cypress/e2e/third-party/donate-page.ts index b5cb1348cd0..e329a25761a 100644 --- a/cypress/e2e/third-party/donate-page.ts +++ b/cypress/e2e/third-party/donate-page.ts @@ -1,6 +1,6 @@ describe('Donate page', () => { it('Donation ', () => { - cy.exec('pnpm run seed'); + cy.task('seed'); cy.login(); cy.visit('/donate'); cy.get('.donation-elements', { timeout: 10000 }).within(() => { diff --git a/tools/scripts/seed/seed-demo-user.js b/tools/scripts/seed/seed-demo-user.js index 7aaed1fdf0f..f401486545e 100644 --- a/tools/scripts/seed/seed-demo-user.js +++ b/tools/scripts/seed/seed-demo-user.js @@ -4,7 +4,28 @@ require('dotenv').config({ path: path.resolve(__dirname, '../../../.env') }); const { MongoClient, ObjectId } = require('mongodb'); const fullyCertifiedUser = require('./certified-user-data'); -const envVariables = process.argv; +const args = process.argv.slice(2); + +const allowedArgs = [ + '--donor', + '--top-contributor', + '--unset-privacy-terms', + 'certified-user' +]; + +// Check for invalid arguments +args.forEach(arg => { + if (!allowedArgs.includes(arg)) + throw new Error( + `Invalid argument ${arg}. Allowed arguments are ${allowedArgs.join(', ')}` + ); +}); + +if (args.includes('certified-user') && args.length > 1) { + throw new Error( + `Invalid arguments. When using 'certified-user', no other arguments are allowed.` + ); +} const log = debug('fcc:tools:seedLocalAuthUser'); const { MONGOHQ_URL } = process.env; @@ -36,9 +57,7 @@ const demoUser = { name: 'Development User', location: '', picture: '', - acceptedPrivacyTerms: envVariables.includes('--unset-privacy-terms') - ? null - : true, + acceptedPrivacyTerms: args.includes('--unset-privacy-terms') ? null : true, sendQuincyEmail: false, currentChallengeId: '', isHonest: false, @@ -62,7 +81,7 @@ const demoUser = { isCollegeAlgebraPyCertV8: false, completedChallenges: [], portfolio: [], - yearsTopContributor: envVariables.includes('--top-contributor') + yearsTopContributor: args.includes('--top-contributor') ? ['2017', '2018', '2019'] : [], rand: 0.6126749173148205, @@ -82,7 +101,7 @@ const demoUser = { badges: { coreTeam: [] }, - isDonating: envVariables.includes('--donor'), + isDonating: args.includes('--donor'), emailAuthLinkTTL: null, emailVerifyTTL: null, keyboardShortcuts: true, @@ -183,7 +202,7 @@ const dropUsers = async function () { const run = async () => { await dropUserTokens(); await dropUsers(); - if (process.argv[2] === 'certified-user') { + if (args.includes('certified-user')) { await user.insertOne(fullyCertifiedUser); await user.insertOne(blankUser); } else {