feat(Cypress): give basic structure to cypress typescript files (#48734)
parent
0168190281
commit
ff95595fa5
|
@ -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');
|
||||
|
|
|
@ -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 = `<h1>Hello</h1>`;
|
||||
cy.get(selectors.editor).as('editor').contains(editorContents);
|
||||
cy.get(selectors.class.reactMonacoEditor)
|
||||
.as('editor')
|
||||
.contains(editorContents);
|
||||
cy.get('@editor').click().focused().type(`{movetoend}<h1>Hello World</h1>`);
|
||||
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 = `<h1>Hello</h1>`;
|
||||
cy.get(selectors.editor).as('editor').contains(editorContents);
|
||||
cy.get(selectors.class.reactMonacoEditor)
|
||||
.as('editor')
|
||||
.contains(editorContents);
|
||||
cy.get('@editor')
|
||||
.click()
|
||||
.focused()
|
|
@ -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');
|
||||
});
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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' ||
|
|
@ -0,0 +1,11 @@
|
|||
export const selectors = {
|
||||
class: {
|
||||
outputText: '.output-text',
|
||||
reactMonacoEditor: '.react-monaco-editor-container'
|
||||
},
|
||||
id: {},
|
||||
data: {},
|
||||
tag: {
|
||||
inputSolution: 'input[name="solution"]'
|
||||
}
|
||||
};
|
|
@ -3,6 +3,6 @@
|
|||
"target": "es5",
|
||||
"lib": ["es5", "dom"]
|
||||
},
|
||||
"include": ["e2e/**/*.ts"],
|
||||
"include": ["e2e/**/*.ts", "support/**/*.ts"],
|
||||
"extends": "../tsconfig-base.json"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue