Protractor Jasmine Reporter + BDD + Azure DevOps - jasmine

I would like to write Jasmine End 2 End Tests in a BDD style. From what I've learned, this means, I have pretty much 4 areas:
Feature
Scenario
stimulus or event
Outcomes to ensure
From my naive view, I would create a test for the "Individual Details" feature like this:
// Feature
describe('Showing Individual Details', () => {
let individualDetailsPage: IndividualDetailsPage;
beforeEach(() => {
individualDetailsPage = new IndividualDetailsPage();
});
// Scenario - New Individual
describe('Given a new Individual', () => {
beforeEach(async () => {
await individualDetailsPage.navigateToDetails('-1');
});
// Incoming Event
describe('When the Details are loaded', () => {
// Ensure outcome
it('Then all Controls are empty', async () => {
expect(individualDetailsPage.firstNameInput.text).toBe('');
expect(individualDetailsPage.lastNameInput.text).toBe('');
expect(individualDetailsPage.birthdateInput.text).toBe('');
});
// Ensure outcome
it('Then the save button is disabled', () => {
expect(individualDetailsPage.saveButton.isEnabled).toBe(false);
});
});
});
});
Therefore, for the Individual Details feature, if a new Individual is set, then the Controls should be empty and the save button disabled.
Still from a naive view, this seems alright. Also running the tests, I see:
Which seems alright. Now the interesting part: I would like to publish this changes to Azure DevOps, therefore I'm using the following code in the protractor config:
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.e2e.json')
});
var jasmineReporters = require('jasmine-reporters');
var junitReporter = new jasmineReporters.JUnitXmlReporter({
savePath: 'testresults',
filePrefix: 'e2e-tests',
consolidateAll: true
});
jasmine.getEnv().addReporter(junitReporter);
}
Unfortunately, the XML is looking like this:
<testsuite name="Showing Individual Details" timestamp="2019-02-04T18:23:33" hostname="localhost" time="2.035" errors="0" tests="0" skipped="0" disabled="0" failures="0">
</testsuite>
<testsuite name="Showing Individual Details.Given a new Individual" timestamp="2019-02-04T18:23:33" hostname="localhost" time="2.033" errors="0" tests="0" skipped="0" disabled="0" failures="0">
</testsuite>
<testsuite name="Showing Individual Details.Given a new Individual.When the Details are loaded" timestamp="2019-02-04T18:23:33" hostname="localhost" time="2.033" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="Showing Individual Details.Given a new Individual.When the Details are loaded" name="Then all Controls are empty" time="1.106" />
<testcase classname="Showing Individual Details.Given a new Individual.When the Details are loaded" name="Then the save button is disabled" time="0.927" />
</testsuite>
Since Azure DevOps only seems to check for the name, I then see:
My problem: I don't know exactly, where my problem lies. I didn't find any good resources regarding "real" BDD with Jasmine, also it seems like the Jasmine Reporter can't be configured that much: https://github.com/larrymyers/jasmine-reporters
Is therefore my code totally wrong, or is it in fact the reporter? And if this is the case, are there alternatives or would I need to "flatten" the XML somehow?

I agree with the comment above, creating your own reporter sound like the way to go. You can format the contents however you like.
I recently responded to another question regarding Jasmine reporter here. I was reformatting my test results into a JSON object and storing them in amazons dynamoDB after each test completed.
Any more questions let me know.

you can use the useFullTestName property:
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
useFullTestName:true,
savePath: 'e2e/output',
filePrefix: 'xmlresults'
}));

I would like to recommend using the Jasmine TRX Reporter instead of the JUnit XML Reporter.
The TRX Reporter also supports adding screenshots to the published test results, which is a big plus in a CI/CD environment.
The screenshot will be available in Azure Devops under the attachments tab of the test case result:
You can add it to your project with:
npm install jasmine-trx-reporter --save-dev
And add it to you protractor config like so:
const TrxReporter = require('jasmine-trx-reporter');
...
onPrepare() {
...
jasmine.getEnv().addReporter(new TrxReporter({
folder: require('path').join(__dirname, './testresults/'),
takeScreenshotsOnlyOnFailures: true
}));
...
And last but not least, change the Publish Test Result step in your Release to use VSTest instead of JUnit and the exported .trx file instead of the .xml file.

Related

Cypress - Unable to run multiple tests

I am very new to cypress automation and have been following though some examples and have ran into an issue that does not appear to be addressed in any video I have seen, where multiple tests in the same 'describe' do not run as expected.
If I create the following code & run it, it all works perfectly:-
describe('My First Test', () => {
it('Open Google', () => {
cy.visit('https://google.co.uk')
cy.get('#L2AGLb > .QS5gu').click()
cy.get('.gLFyf').type('Automation Step by Step{Enter}')
})
})
I have then attempted to split up the test into individual tests, as follows:-
describe('My First Test', () => {
it('Open Google', () => {
cy.visit('https://google.co.uk')
})
it('Confirm warning', () => {
cy.get('#L2AGLb > .QS5gu').click()
cy.get('.gLFyf').type('Automation Step by Step{Enter}')
})
it('Confirm warning', () => {
cy.get('.gLFyf').type('Automation Step by Step{Enter}')
})
})
The problem now is that after opening Chrome and then going into the next test, which should allow me to type the text, a 'default blank page' is displayed and the tests then fail.
What am I missing here to be able to run these three tests fully?
Code in VS Code
Error after opening Chrome & attempting to type in box
As above really, I was hoping to be able to run all three simple tests together.
EDIT - I rolled back my version of Cypress to 10.10.0 and it works perfectly, so no idea what has changed on the latest version released yesterday.
Try it with Test Isolation turned to false.
Best Practice: Tests should always be able to be run independently from one another and still pass
This was added in Cypress 12.0.0.
But if you want to play without it,
Test Isolation Disabled
testIsolation
beforeEach test
true
- clears page by visiting about:blank
- clears cookies in all domains
- local storage in all domains
- session storage in all domains
false
does not alter the current browser context
cypress.config.js
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
testIsolation: false,
},
})
You should visit your page for every test. You can put the cy.visit in a beforeEach function.

How to stop cypress from closing browser after each test case (it)?

I have a cy.js file like this
/// <reference types="cypress" />
context("Dummy test cases", () => {
it("open Google", () => {
cy.visit("www.google.com");
});
it("search a keyword", () => {
cy.get(".gLFyf").type("cypress{enter}");
});
});
As you can see I've 2 test cases. 1 is to open a website and the other is to do other tasks.
But the problem is that after finishing the first 'it' (test case 1), the browser closes and then the next case fails because there is no active browser.
Can you help me how to stop cypress from closing the browser after the execution of each test case?
I found Cypress is quite opinionated about some things, one at the top of the list is "test isolation" which means one test must not influence another test.
Note each it() is a test.
To make your code work, you must turn off test isolation.
If the cypress.config.js file add the option
const { defineConfig } = require("cypress");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
testIsolation: false,
},
})
Same if you are using typescript.
This got added in the new Version Cypress 12.0.0, in their
Changelogs its at the feature section:
Added a new configuration option called testIsolation, which defaults to true.
As #Joylette already said, in your config file just use testIsolation: false to deactivate it. If you ever use an older version use testIsolation: off, they renamed it in the newest version.

converting cypress BDD tests to mocha format

i have suit of BDD tests written in cypress-typescript, which i would like to convert to mocha format. this is contents of a sample test.spec.ts file
///<reference types='cypress'/>
describe('mock test', () => {
console.log('hello i have execuited');
});
this is the contents of cypress.jason file-
{
"testFiles": "**.spec.ts",
"ignoreTestFiles": "cypress/**/*.ts"
}
upon execuition of the command yarn cypress open via the terminal, i can see the tests under the cypress windown but when i try to run them i get this error message-
No tests found.
Cypress could not detect tests in this file.
Error: The service was stopped
at C:\Users\------\IdeaProjects\kura\node_modules\esbuild\lib\main.js:1335:25
at C:\Users\------\IdeaProjects\kura\node_modules\esbuild\lib\main.js:666:9
at Socket.afterClose (C:\Users\------\IdeaProjects\kura\node_modules\esbuild\lib\main.js:644:7)
at Socket.emit (node:events:539:35)
at endReadableNT (node:internal/streams/readable:1345:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
any help highly appreciated
The describe() block is simply a way to group our tests, whereas it() blocks are like individual tests.
You need to create individual tests within your describe block like so:
/// <reference types="cypress" />
describe('example to-do app', () => {
it('displays two todo items by default', () => {
console.log('hello i have execuited');
})
it('can add new todo items', () => {
console.log('hello i have execuited');
})
})

No Code Coverage for Fastify Integration Tests Using NYC/Istanbul written in Typescript

I'm currently trying to get code coverage on my fastify routes using Mocha and NYC.
I've tried instrumenting the code beforehand and then running the tests on the instrumented code as well as just trying to setup NYC in various ways to get it to work right.
Here is my current configuration. All previous ones produced the same code coverage output):
nyc config
"nyc": {
"extends": "#istanbuljs/nyc-config-typescript",
"extension": [
".ts",
".tsx"
],
"exclude": [
"**/*.d.ts",
"**/*.test.ts"
],
"reporter": [
"html",
"text"
],
"sourceMap": true,
"instrument": true
}
Route file:
const routes = async (app: FastifyInstance, options) => {
app.post('/code', async (request: FastifyRequest, response: FastifyReply<ServerResponse>) => {
// route logic in here
});
};
The integration test:
import * as fastify from fastify;
import * as sinon from 'sinon';
import * as chai from 'chai';
const expect = chai.expect;
const sinonChai = require('sinon-chai');
chai.use(sinonChai);
describe('When/code POST is called', () => {
let app;
before(() => {
app = fastify();
// load routes for integration testing
app.register(require('../path/to/code.ts'));
});
after(() => {
app.close();
});
it('then a code is created and returned', async () => {
const {statusCode} = await apiTester.inject({
url: '/code',
method: 'POST',
payload:{ code: 'fake_code' }
});
expect(statusCode).to.equal(201);
});
});
My unit test call looks like the following:
nyc mocha './test/unit/**/*.test.ts' --require ts-node/register --require source-map-support/register --recursive
I literally get 5% code coverage just for the const routes =. I'm really banging my head trying to figure this one out. Any help would be greatly appreciated! None of the other solutions I have investigated on here work.
I have a detailed example for typescript + mocha + nyc. It also contains fastify tests including route tests (inject) as well as mock + stub and spy tests using sinon. All async await as well.
It's using all modern versions and also covers unused files as well as VsCode launch configs. Feel free to check it out here:
https://github.com/Flowkap/typescript-node-template
Specifically I think that
instrumentation: true
messes up the results. Heres my working .nycrc.yml
extends: "#istanbuljs/nyc-config-typescript"
reporter:
- html
- lcovonly
- clover
# those 2 are for commandline outputs
- text
- text-summary
report-dir: coverage
I have proper coverage even for mocked ans tub parts of fastify in my above mentioned example.

Webstorm Karma test debugging - breakpoint not hit

I have installed the chrome jet brains extension
I have tests like this:
describe('Service tests', function () {
beforeEach(module('app'));
it('should have a Service', inject(function($injector) {
var exist = $injector.has('dataService');
etc
but no luck getting breakpoints to hit any where in the tests. I can get the debugger to break when writing debugger, but an unable to step through.
Do you have karma-coverage set up in your karma config? It uses instrumented code, so debugging is not possible. Related tickets: http://github.com/karma-runner/karma/issues/630, http://youtrack.jetbrains.com/issue/WEB-8443
If you are building with Webpack you might need to specify the devtools option in your webpack config property in karma.conf.js like this:
module.exports = (config) => {
config.set({
webpack: {
...,
devtool: 'inline-source-map'
}
})
};
This solution works for me with Webpack v3.
If by any chance you are using Angular and you have removed all the coverage related stuff from your karma.config file and are still unable to hit the breakpoints, look into the angular.json. It might be having the codeCoverage bit set to true.
"test": {
...
"options": {
...
"codeCoverage": false,
...
}
...
}

Resources