Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to Cypress 12 #908

Merged
merged 18 commits into from
May 12, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 32 additions & 7 deletions e2e-cypress/Jenkinsfile.template
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,34 @@

@Library('ods-jenkins-shared-library@@shared_library_ref@') _

node {
dockerRegistry = env.DOCKER_REGISTRY
}

odsComponentPipeline(
imageStreamTag: '@ods_namespace@/jenkins-agent-nodejs16:@agent_image_tag@',
podContainers: [
containerTemplate(
name: 'jnlp',
image: "${dockerRegistry}/ods/jenkins-agent-nodejs16:@shared_library_ref@",
workingDir: '/tmp',
resourceRequestCpu: '10mi',
resourceLimitCpu: '300mi',
resourceRequestMemory: '1Gi',
resourceLimitMemory: '2Gi',
alwaysPullImage: true,
args: '${computer.jnlpmac} ${computer.name}'
)
],
branchToEnvironmentMapping: [
'master': 'dev',
// 'release/': 'test'
]
) { context ->

stageTest(context)
odsComponentStageScanWithSonar(context)
}

}

def stageTest(def context) {
stage('Integration Test') {
Expand All @@ -35,13 +53,20 @@ def stageTest(def context) {
]) {
sh 'npm install'
def status = sh(script: 'npm run e2e', returnStatus: true)
junit(testResults:'test-results/*.xml', allowEmptyResults: true)
stash(name: "installation-test-reports-junit-xml-${context.componentId}-${context.buildNumber}", includes: 'test-results/installation-junit.xml', allowEmpty: true)
stash(name: "integration-test-reports-junit-xml-${context.componentId}-${context.buildNumber}", includes: 'test-results/integration-junit.xml', allowEmpty: true)
stash(name: "acceptance-test-reports-junit-xml-${context.componentId}-${context.buildNumber}", includes: 'test-results/acceptance-junit.xml', allowEmpty: true)
sh 'npm run combine:reports'
junit(testResults:'build/test-results/*.xml', allowEmptyResults: true)
stash(name: "installation-test-reports-junit-xml-${context.componentId}-${context.buildNumber}", includes: 'build/test-results/installation-junit.xml', allowEmpty: true)
stash(name: "integration-test-reports-junit-xml-${context.componentId}-${context.buildNumber}", includes: 'build/test-results/integration-junit.xml', allowEmpty: true)
stash(name: "acceptance-test-reports-junit-xml-${context.componentId}-${context.buildNumber}", includes: 'build/test-results/acceptance-junit.xml', allowEmpty: true)
zip zipFile: 'cypress/videos.zip', archive: false, dir: 'cypress/videos'
stash(name: "acceptance-test-videos-${context.componentId}-${context.buildNumber}", includes: 'cypress/videos.zip', allowEmpty: true)
archiveArtifacts artifacts: 'cypress/videos.zip', fingerprint: true, daysToKeep: 2, numToKeep: 3
if (status != 0) {
error 'Executing tests failed!'
zip zipFile: 'cypress/screenshots.zip', archive: false, dir: 'cypress/screenshots'
stash(name: "acceptance-test-screenshots-${context.componentId}-${context.buildNumber}", includes: 'cypress/screenshots.zip', allowEmpty: true)
archiveArtifacts artifacts: 'cypress/screenshots.zip', fingerprint: true, daysToKeep: 2, numToKeep: 3
}
return status
}
}
}
6 changes: 6 additions & 0 deletions e2e-cypress/changelog.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already a changelog for the whole repository (https://github.com/opendevstack/ods-quickstarters/blob/master/CHANGELOG.md). AFAIK we don't have per-QS changelogs so far. I guess there should be an entry there instead of creating a separate changelog here. I'd keep it a one-line entry, e.g. something like

- Upgraded to Cypress 12, improve login support, add video support ([#899](https://github.com/opendevstack/ods-quickstarters/issues/899))

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
### Added
- New login example with cy.origin() ([#899](https://github.com/opendevstack/ods-quickstarters/issues/899))
- Upload videos ([#899](https://github.com/opendevstack/ods-quickstarters/issues/899))

### Changes
- Upgraded to Cypress 12 ([#899](https://github.com/opendevstack/ods-quickstarters/issues/899))
26 changes: 24 additions & 2 deletions e2e-cypress/files/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,32 @@ This end-to-end testing project was generated from the *e2e-cypress* ODS quickst

With the introduction of the release manager concept in OpenDevStack 3, e2e test quickstarters are expected to run tests in three different stages (installation, integration & acceptance) and generate a JUnit XML result file for each of these stages.

Please note that each stage is executed with its own Cypress configuration file (`cypress-<stage>.json`) that can be adjusted to your particular case (e.g. base URL etc.). Make sure to keep `junit` as reporter and to not change the output path for the JUnit results files as they will be stashed by Jenkins and reused by the release manager.
Please note that each stage is executed with its own Cypress configuration file (`cypress-<stage>.config.ts`) that can be adjusted to your particular case (e.g. base URL etc.). Make sure to keep `junit` as reporter and to not change the output path for the JUnit results files as they will be stashed by Jenkins and reused by the release manager.

## Running end-to-end tests

Run `npm run e2e` to execute all end-to-end tests via [Cypress](https://www.cypress.io) against the test instance of the front end.

## Local development

Run `npm start` to develop the e2e tests. The tests will automatically rebuild and run, if you change any of the source files. Ideally the test will run against a local instance of the front end, e.g. `http://localhost:4200` for an Angular app. This destination is configurable in the `cypress.json` file.
Run `npm start` to develop the e2e tests. The tests will automatically rebuild and run, if you change any of the source files. Ideally the test will run against a local instance of the front end, e.g. `http://localhost:4200` for an Angular app. This destination is configurable in the `cypress.config.ts` file.

## How to upload images or videos to Nexus

Screenshots are only taken when test fails.
1. Open the Jenkinsfile
2. Replace `stageTest(context)` by the following lines:
```
def status = stageTest(context)
if (status != 0) {
odsComponentStageUploadToNexus(context,
[
distributionFile: 'tests/screenshots.zip',
repository: 'leva-documentation',
repositoryType: 'raw',
targetDirectory: "${targetDirectory}"])
}
```

## Reports
From [Merging reports across spec files](https://docs.cypress.io/guides/tooling/reporters#Merging-reports-across-spec-files): each spec file is processed completely separately during each cypress run execution. Thus each spec run overwrites the previous report file. To preserve unique reports for each spec file, use the `[hash]` in the `mochaFile` filename.
Expand All @@ -23,6 +40,11 @@ In order to generate one xml report per test type (installation, integration and

## E2e test user authentication

With Cypress 12 version is now available `cy.origin()` that allows you to handle redirections. This funcionality eases the login handling.
garcanam marked this conversation as resolved.
Show resolved Hide resolved
See `./support/e2e.ts` for a generic login example.

#### *Obsolete*

This quickstarter provides a login command for Azure SSO with MSALv2 (`./support/msalv2-login.ts`) as well as sample code for a generic login (`./support/generic-login.ts`).

## Links
Expand Down
22 changes: 22 additions & 0 deletions e2e-cypress/files/cypress-acceptance.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { defineConfig } from 'cypress'
import setupNodeEvents from './plugins/index.js'
export default defineConfig({
reporter: 'junit',
reporterOptions: {
mochaFile: 'build/test-results/acceptance-junit-[hash].xml',
toConsole: true,
},
e2e: {
baseUrl: 'https://www.w3schools.com',
fixturesFolder: "fixtures",
specPattern: 'tests/acceptance/*.cy.ts',
supportFile: "support/e2e.ts",
viewportWidth: 1376,
viewportHeight: 660,
experimentalModifyObstructiveThirdPartyCode:true,
video: true,
setupNodeEvents(on, config) {
return require('./plugins/index.js')(on, config)
},
},
})
14 changes: 0 additions & 14 deletions e2e-cypress/files/cypress-acceptance.json

This file was deleted.

23 changes: 23 additions & 0 deletions e2e-cypress/files/cypress-installation.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { defineConfig } from 'cypress'
import setupNodeEvents from './plugins/index.js'
export default defineConfig({
//projectId: '[Define your project id for Cypress cloud]',
reporter: 'junit',
reporterOptions: {
mochaFile: 'build/test-results/installation-junit-[hash].xml',
toConsole: true,
},
e2e: {
baseUrl: 'https://www.w3schools.com',
fixturesFolder: "fixtures",
specPattern: 'tests/installation/*.cy.ts',
supportFile: "support/e2e.ts",
viewportWidth: 1376,
viewportHeight: 660,
experimentalModifyObstructiveThirdPartyCode:true,
video: true,
setupNodeEvents(on, config) {
return require('./plugins/index.js')(on, config)
},
},
})
14 changes: 0 additions & 14 deletions e2e-cypress/files/cypress-installation.json

This file was deleted.

23 changes: 23 additions & 0 deletions e2e-cypress/files/cypress-integration.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { defineConfig } from 'cypress'
import setupNodeEvents from './plugins/index.js'
export default defineConfig({
//projectId: '[Define your project id for Cypress cloud]',
reporter: 'junit',
reporterOptions: {
mochaFile: 'build/test-results/integration-junit-[hash].xml',
toConsole: true,
},
e2e: {
baseUrl: 'https://www.w3schools.com',
fixturesFolder: "fixtures",
specPattern: 'tests/integration/*.cy.ts',
supportFile: "support/e2e.ts",
viewportWidth: 1376,
viewportHeight: 660,
experimentalModifyObstructiveThirdPartyCode:true,
video: true,
setupNodeEvents(on, config) {
return require('./plugins/index.js')(on, config)
},
},
})
14 changes: 0 additions & 14 deletions e2e-cypress/files/cypress-integration.json

This file was deleted.

22 changes: 22 additions & 0 deletions e2e-cypress/files/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { defineConfig } from 'cypress'
import setupNodeEvents from './plugins/index.js'
export default defineConfig({
reporter: 'junit',
reporterOptions: {
mochaFile: 'build/test-results/tests-[hash].xml',
toConsole: true,
},
e2e: {
baseUrl: 'https://www.w3schools.com',
fixturesFolder: "fixtures",
specPattern: 'tests/**/*.cy.ts',
supportFile: "support/e2e.ts",
viewportWidth: 1376,
viewportHeight: 660,
experimentalModifyObstructiveThirdPartyCode: true,
video: true,
setupNodeEvents(on, config) {
return require('./plugins/index.js')(on, config)
},
},
})
10 changes: 0 additions & 10 deletions e2e-cypress/files/cypress.json

This file was deleted.

18 changes: 10 additions & 8 deletions e2e-cypress/files/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@
"start": "npm run cypress:open",
"cypress:open": "cypress open",
"cypress:run": "cypress run --browser=chrome",
"cypress:run-installation": "npm run cypress:run -- --config-file cypress-installation.json",
"cypress:run-integration": "npm run cypress:run -- --config-file cypress-integration.json",
"cypress:run-acceptance": "npm run cypress:run -- --config-file cypress-acceptance.json",
"junit-installation-report": "jrm ./test-results/installation-junit.xml './test-results/installation/*.xml'",
"junit-integration-report": "jrm ./test-results/integration-junit.xml './test-results/integration/*.xml'",
"junit-acceptance-report": "jrm ./test-results/acceptance-junit.xml './test-results/acceptance/*.xml'",
"cypress:run-installation": "npm run cypress:run -- --config-file cypress-installation.config.ts",
"cypress:run-integration": "npm run cypress:run -- --config-file cypress-integration.config.ts",
"cypress:run-acceptance": "npm run cypress:run -- --config-file cypress-acceptance.config.ts",
"junit-installation-report": "jrm build/test-results/installation-junit.xml 'build/test-results/installation-*.xml'",
"junit-integration-report": "jrm build/test-results/integration-junit.xml 'build/test-results/integration-*.xml'",
"junit-acceptance-report": "jrm build/test-results/acceptance-junit.xml 'build/test-results/acceptance-*.xml'",
"delete-junit-results": "rimraf build/test-results",
"e2e": "npm-run-all delete-junit-results cypress:run-installation cypress:run-integration cypress:run-acceptance junit-installation-report junit-integration-report junit-acceptance-report"
"e2e": "npm-run-all delete-junit-results cypress:run-installation cypress:run-integration cypress:run-acceptance",
"combine:reports": "npm-run-all junit-installation-report junit-integration-report junit-acceptance-report"
},
"private": true,
"devDependencies": {
"@types/node": "^17.0.23",
"cypress": "^9.5.3",
"cypress": "^12.9.0",
"cypress-junit-reporter": "^1.3.1",
"junit-report-merger": "^5.0.0",
"npm-run-all": "^4.1.5",
"rimraf": "^3.0.2",
Expand Down
69 changes: 69 additions & 0 deletions e2e-cypress/files/support/e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//For more details, you can follow this link:
//https://docs.cypress.io/guides/end-to-end-testing/azure-active-directory-authentication#Microsoft-AAD-Application-Setup
function loginViaAAD(username: string, password: string) {

//Go to your application URL and trigger the login.
cy.visit('')

//If needed, navigate and click on the login button.
//As an example:
//cy.get('button#signIn').click()

//Login to your AAD tenant.
//ATENTION: The redirection can happen at the 'login.microsoftonline.com' and also it might redirect as well to 'login.live.com'
cy.origin(
'https://login.microsoftonline.com',
{
args: {
username,
password,
},
},
({ username, password }) => {
cy.get('input[type="email"]').type(username, {
log: false,
})
cy.get('input[type="submit"]').click()
cy.get('input[type="password"]').type(password, {
log: false,
})
cy.get('input[type="submit"]').click()
}
)

//Depending on the user and how they are registered with Microsoft, the origin may go to live.com
garcanam marked this conversation as resolved.
Show resolved Hide resolved
//cy.origin(
// 'login.live.com',
// {
// args: {
// password,
// },
// },
// ({ password }) => {
// cy.get('input[type="password"]').type(password, {
// log: false,
// })
// cy.get('input[type="submit"]').click()
// cy.get('#idBtn_Back').click()
// }
//)

// Ensure Microsoft has redirected us back to the sample app with our logged in user.
cy.url().should('equal', Cypress.config().baseUrl)
}

//See how to use it at:
//tests/acceptance/acceptance.spec.cy.ts
Cypress.Commands.add('loginToAAD', (username: string, password: string) => {
const log = Cypress.log({
displayName: 'Azure Active Directory Login',
message: [`🔐 Authenticating | ${username}`],
autoEnd: false,
})
log.snapshot('before')

loginViaAAD(username, password)

log.snapshot('after')
log.end()
})
16 changes: 0 additions & 16 deletions e2e-cypress/files/support/index.ts

This file was deleted.

Loading