From ff95595fa50d9085166dc07035d84364125099e0 Mon Sep 17 00:00:00 2001 From: Sem Bauke Date: Mon, 12 Dec 2022 18:07:03 +0100 Subject: [PATCH] feat(Cypress): give basic structure to cypress typescript files (#48734) --- .../e2e/default/learn/challenges/backend.ts | 11 +-- .../{code-storage.js => code-storage.ts} | 13 +-- .../challenges/{codeally.js => codeally.ts} | 0 cypress/support/commands.js | 84 ------------------- cypress/support/commands.ts | 75 +++++++++++++++++ cypress/support/{e2e.js => e2e.ts} | 2 +- cypress/support/selectors.ts | 11 +++ cypress/tsconfig.json | 2 +- 8 files changed, 99 insertions(+), 99 deletions(-) rename cypress/e2e/default/learn/challenges/{code-storage.js => code-storage.ts} (77%) rename cypress/e2e/default/learn/challenges/{codeally.js => codeally.ts} (100%) delete mode 100644 cypress/support/commands.js create mode 100644 cypress/support/commands.ts rename cypress/support/{e2e.js => e2e.ts} (97%) create mode 100644 cypress/support/selectors.ts diff --git a/cypress/e2e/default/learn/challenges/backend.ts b/cypress/e2e/default/learn/challenges/backend.ts index 88f361f95c2..97290fae85c 100644 --- a/cypress/e2e/default/learn/challenges/backend.ts +++ b/cypress/e2e/default/learn/challenges/backend.ts @@ -1,14 +1,11 @@ +import { selectors } from '../../../../support/selectors'; + const locations = { index: 'learn/back-end-development-and-apis/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'; @@ -26,7 +23,7 @@ describe('Backend challenge', function () { it('does not generate unhandled errors on submission', () => { cy.visit(locations.index); - cy.get(selectors.input).type('https://example.com'); + cy.get(selectors.tag.inputSolution).type('https://example.com'); // temporary fix until https://github.com/cypress-io/cypress/issues/20562 is fixed cy.contains(`I've completed this challenge`) @@ -36,7 +33,7 @@ describe('Backend challenge', function () { // .type('{enter}') .then(() => { - cy.get(selectors.defaultOutput) + cy.get(selectors.class.outputText) .contains(runningOutput) .contains(finishedOutput); cy.contains(unhandledErrorMessage).should('not.exist'); diff --git a/cypress/e2e/default/learn/challenges/code-storage.js b/cypress/e2e/default/learn/challenges/code-storage.ts similarity index 77% rename from cypress/e2e/default/learn/challenges/code-storage.js rename to cypress/e2e/default/learn/challenges/code-storage.ts index cdf490f62b5..e9c3e711026 100644 --- a/cypress/e2e/default/learn/challenges/code-storage.js +++ b/cypress/e2e/default/learn/challenges/code-storage.ts @@ -1,7 +1,4 @@ -const selectors = { - defaultOutput: '.output-text', - editor: '.react-monaco-editor-container' -}; +import { selectors } from '../../../../support/selectors'; const location = '/learn/responsive-web-design/basic-html-and-html5/say-hello-to-html-elements'; @@ -13,7 +10,9 @@ describe('Challenge with editor', function () { it('renders seed code without localStorage', () => { const editorContents = `

Hello

`; - cy.get(selectors.editor).as('editor').contains(editorContents); + cy.get(selectors.class.reactMonacoEditor) + .as('editor') + .contains(editorContents); cy.get('@editor').click().focused().type(`{movetoend}

Hello World

`); cy.reload(); cy.get('@editor', { timeout: 10000 }).contains(editorContents); @@ -21,7 +20,9 @@ describe('Challenge with editor', function () { it('renders code from localStorage after "Ctrl + S"', () => { const editorContents = `

Hello

`; - cy.get(selectors.editor).as('editor').contains(editorContents); + cy.get(selectors.class.reactMonacoEditor) + .as('editor') + .contains(editorContents); cy.get('@editor') .click() .focused() diff --git a/cypress/e2e/default/learn/challenges/codeally.js b/cypress/e2e/default/learn/challenges/codeally.ts similarity index 100% rename from cypress/e2e/default/learn/challenges/codeally.js rename to cypress/e2e/default/learn/challenges/codeally.ts diff --git a/cypress/support/commands.js b/cypress/support/commands.js deleted file mode 100644 index 0144c35c2d9..00000000000 --- a/cypress/support/commands.js +++ /dev/null @@ -1,84 +0,0 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add('login', (email, password) => {}); -// -// -// -- This is a child command -- -// Cypress.Commands.add( -// 'drag', -// { prevSubject: 'element' }, -// (subject, options) => {} -// ); -// -// -// -- This is a dual command -- -// Cypress.Commands.add( -// 'dismiss', -// { prevSubject: 'optional' }, -// (subject, options) => {} -// ); -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite('visit', (originalFn, url, options) => {}); - -Cypress.Commands.add('login', () => { - cy.visit(`${Cypress.env('API_LOCATION')}/signin`); - cy.contains('Welcome back'); -}); - -Cypress.Commands.add('preserveSession', () => { - Cypress.Cookies.preserveOnce( - 'jwt_access_token', - 'csrf_token', - '_csrf', - 'connect.sid' - ); -}); - -Cypress.Commands.add('setPrivacyTogglesToPublic', () => { - cy.get('#privacy-settings') - .find('.toggle-not-active') - .each(element => { - cy.wrap(element).click().should('have.class', 'toggle-active'); - }); - cy.get('[data-cy=save-privacy-settings]').click(); - cy.get('#honesty-policy').find('button').click(); - cy.contains('You have accepted our Academic Honesty Policy'); -}); - -Cypress.Commands.add('goToSettings', () => { - cy.visit('/settings'); - - // Setting aliases here - cy.get('[data-cy=username-input]').as('usernameInput'); - cy.get('[data-cy=username-form]').as('usernameForm'); -}); - -Cypress.Commands.add('typeUsername', username => { - cy.get('@usernameInput') - .clear({ force: true }) - .type(username, { force: true }); -}); - -Cypress.Commands.add('resetUsername', () => { - cy.goToSettings(); - - cy.typeUsername('developmentuser'); - - cy.contains('Username is available'); - - cy.get('@usernameInput').type('{enter}', { force: true, release: false }); - - cy.contains('Account Settings for developmentuser').should('be.visible'); -}); diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts new file mode 100644 index 00000000000..bde20d1d825 --- /dev/null +++ b/cypress/support/commands.ts @@ -0,0 +1,75 @@ +const login = () => { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + cy.visit(`${Cypress.env('API_LOCATION')}/signin`); + cy.contains('Welcome back'); +}; + +const preserveSession = () => { + Cypress.Cookies.preserveOnce( + 'jwt_access_token', + 'csrf_token', + '_csrf', + 'connect.sid' + ); +}; + +const setPrivacyTogglesToPublic = () => { + cy.get('#privacy-settings') + .find('.toggle-not-active') + .each(element => { + cy.wrap(element).click().should('have.class', 'toggle-active'); + }); + cy.get('[data-cy=save-privacy-settings]').click(); + cy.get('#honesty-policy').find('button').click(); + cy.contains('You have accepted our Academic Honesty Policy'); +}; + +const goToSettings = () => { + cy.visit('/settings'); + + // Setting aliases here + cy.get('[data-cy=username-input]').as('usernameInput'); + cy.get('[data-cy=username-form]').as('usernameForm'); +}; + +const typeUsername = (username: string) => { + cy.get('@usernameInput') + .clear({ force: true }) + .type(username, { force: true }); +}; + +const resetUsername = () => { + cy.goToSettings(); + + cy.typeUsername('developmentuser'); + + cy.contains('Username is available'); + + cy.get('@usernameInput').type('{enter}', { force: true, release: false }); + + cy.contains('Account Settings for developmentuser').should('be.visible'); +}; + +Cypress.Commands.add('login', login); + +Cypress.Commands.add('preserveSession', preserveSession); + +Cypress.Commands.add('setPrivacyTogglesToPublic', setPrivacyTogglesToPublic); + +Cypress.Commands.add('goToSettings', goToSettings); + +Cypress.Commands.add('typeUsername', typeUsername); + +Cypress.Commands.add('resetUsername', resetUsername); + +// eslint-disable-next-line @typescript-eslint/no-namespace +declare namespace Cypress { + interface Chainable { + login: typeof login; + preserveSession: typeof preserveSession; + setPrivacyTogglesToPublic: typeof setPrivacyTogglesToPublic; + goToSettings: typeof goToSettings; + typeUsername: typeof typeUsername; + resetUsername: typeof resetUsername; + } +} diff --git a/cypress/support/e2e.js b/cypress/support/e2e.ts similarity index 97% rename from cypress/support/e2e.js rename to cypress/support/e2e.ts index e46fc952ca2..aec145ce836 100644 --- a/cypress/support/e2e.js +++ b/cypress/support/e2e.ts @@ -25,7 +25,7 @@ Cypress.on('uncaught:exception', err => { console.log('Cypress detected uncaught exception', err.name); // Rapidly cy.visiting pages seems to cause uncaught exceptions. It remains // unclear why this is happening, but we need to ignore them in testing so - // that we can test other behaviour. + // that we can test other behavior. if ( err.name === 'NS_ERROR_UNEXPECTED' || err.name === 'ChunkLoadError' || diff --git a/cypress/support/selectors.ts b/cypress/support/selectors.ts new file mode 100644 index 00000000000..256faa80963 --- /dev/null +++ b/cypress/support/selectors.ts @@ -0,0 +1,11 @@ +export const selectors = { + class: { + outputText: '.output-text', + reactMonacoEditor: '.react-monaco-editor-container' + }, + id: {}, + data: {}, + tag: { + inputSolution: 'input[name="solution"]' + } +}; diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index c24d3ad33a8..32e2d08fdb9 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -3,6 +3,6 @@ "target": "es5", "lib": ["es5", "dom"] }, - "include": ["e2e/**/*.ts"], + "include": ["e2e/**/*.ts", "support/**/*.ts"], "extends": "../tsconfig-base.json" }