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');
})
})
Related
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.
I am trying add functions to this (which is a Mocha Context) in tests, so I can do e.g.
describe('my spec', () => {
it('should work', function () {
this.sayHelloWorld();
})
})
In an empty folder I call
yarn add cypress
yarn cypress open
so that default config files are created. It also creates a sample test in cypress/e2e/spec.cy.js.
I can run the sample test without problem. But if I add
import { Context } from "mocha";
to cypress/support/e2e.js I get
Error: Webpack Compilation Error
./cypress/support/e2e.js
Module not found: Error: Can't resolve 'mocha' in '...\support'
resolve 'mocha' in '...\support'
Parsed request is a module
So I installed Mocha, the same version which is in devDependencies of Cypress (see package.json):
yarn add mocha#3.5.3
My package.json now looks like this:
{
"dependencies": {
"cypress": "^10.4.0",
"mocha": "3.5.3"
}
}
Now that import line passes. But this fails:
import { Context } from "mocha";
Context.prototype.sayHelloWorld = () => console.log("hello world");
Error:
> Cannot read properties of undefined (reading 'prototype')
Why is that? In comparison adding something to String.prototype works.
Also in comparison: Again in an empty folder:
yarn add mocha#3.5.3
And in test/test.js:
const { Context } = require("mocha");
it("should work", function () {
Context.prototype.sayHelloWorld = () => console.log("hello world");
this.sayHelloWorld();
});
Now yarn mocha works (says hello world).
What is going on in Cypress? Possibly a bug?
Solution:
no import { Context } from "mocha";
add functions like that:
Mocha.Context.prototype.sayHelloWorld = function () {
cy.log('hello world');
};
I want to add screenshots for passing tests in the mochawesome html report.
I have managed to add screenshots for a failing test in the html report via the following and was wondering if this could be updated to support screenshots for passing tests?
index.js
import addContext from 'mochawesome/addContext'
Cypress.on('test:after:run', (test, runnable) => {
if (test.state === 'failed') {
addContext({test}, { title: "Screenshot", value:`${Cypress.config('screenshotsFolder')}/${Cypress.spec.name}/${runnable.parent.title} -- ${test.title} (failed).png` })
}
})
How do I conditionally skip a test if the URL contains "xyz"?
some tests that run in the QA environment "abc" should not be run in Production "xyz" environment.
I've not been able to find a good example of conditionally checking for environment to trigger a test. The baseURL needs to be checked dynamically and the test skipped preferably in the beforeEach.
running cypress 6.2.0
beforeEach(() => {
login.loginByUser('TomJones');
cy.visit(`${environment.getBaseUrl()}${route}`);
});
it('test page', function () {
if environment.getBaseUrl().contains("xyz")
then *skip test*
else
cy.intercept('GET', '**/some-api/v1/test*').as('Test'););
cy.get('#submitButton').click();
})
Potential Solution (tested and tried successfully):
I used a combination of filtering (grouping) and folder structures via CLI
I set folders /integrations/smokeTest/QA and /integrations/smokeTest/Prod/
1.QA Test Run:
npm run *cy:filter:qa* --spec "cypresss/integration/smokeTests/QA/*-spec.ts"
2.Run All (both QA and PROD tests)
npm run cypress:open --spec "cypresss/integration/smokeTests/*/*-spec.ts"
3. Prod Test Run:
npm run cy:filter:prod --spec "cypresss/integration/smokeTests/PROD*/*-spec.ts"
Normally I wouldn't write a custom command just to exercise one Cypress command, but in this case it's useful to obtain the global test context this.
Using the function form of callback with the custom command allows access to this, then you are free to use arrow functions on the test themselves.
Cypress.Commands.add('skipWhen', function (expression) {
if (expression) {
this.skip()
}
})
it('test skipping with arrow function', () => {
cy.skipWhen(Cypress.config('baseUrl').includes('localhost'));
// NOTE: a "naked" expect() will not be skipped
// if you call your custom command within the test
// Wrap it in a .then() to make sure it executes on the command queue
cy.then(() => {
expect('this.stackOverflow.answer').to.eq('a.better.example')
})
})
I would add a helper method which you can call from any Mocha.Context (at the time of writing, any it, describe, or context block).
// commands.ts
declare global {
// eslint-disable-next-line #typescript-eslint/no-namespace
namespace Cypress {
interface Chainable {
/**
* Custom command which will skip a test or context based on a boolean expression.
*
* You can call this command from anywhere, just make sure to pass in the the it, describe, or context block you wish to skip.
*
* #example cy.skipIf(yourCondition, this);
*/
skipIf(expression: boolean, context: Mocha.Context): void;
}
}
}
Cypress.Commands.add(
'skipIf',
(expression: boolean, context: Mocha.Context) => {
if (expression) context.skip.bind(context)();
}
);
And from your spec:
describe('Events', () => {
const url = `${environment.getBaseUrl()}${route}`;
before(function () {
cy.visit(url);
cy.skipIf(url.includes('xyz'), this);
});
context('Nested context', () => {
it('test', function () {
cy.skipIf(url.includes('abc'), this);
expect(this.stackOverflow.answer).to.be('accepted');
});
});
});
Now you have a reusable custom command that you can call from anywhere to conditionally skip tests based on any expression that evaluates to a boolean. Careful of classic JS equality and definition gotchas (read more about equality in JS here).
I am trying to use mocha-allure-reporter in Cypress. I installed mocha and mocha-allure-reporter as dev dependencies and mentioned mocha-allure-reporter as the reporter in cypress.json.
I tried the below code quoted in the example section of mocha allure page:
require('mocha-allure-reporter');
describe("simple test demo", () => {
const testStep = allure.createStep("initial", () => {
console.log("First Test")
});
it("simple passed test", () => {
testStep();
});
}
However, I am getting the following error:
Uncaught TypeError: Cannot read property 'Base' of undefined
...at the first line itself:
require('mocha-allure-reporter')
Upon looking on console, I see that the error is originated at line - var Base = require("mocha").reporters.Base in the Allure reporter :
var Base = require("mocha").reporters.Base;
var Allure = require("allure-js-commons");
...
...
global.allure = new Runtime(allureReporter);
/**
* Initialize a new `Allure` test reporter.
*
* #param {Runner} runner
* #param {Object} opts mocha options
* #api public
*/
function AllureReporter(runner, opts) {
...
...
Please note that the following output xml file is getting created in the allure-results directory once the execution is done.
<?xml version='1.0'?>
<ns2:test-suite xmlns:ns2='urn:model.allure.qatools.yandex.ru' start='1547481439243' stop='1547481439477'>
<name></name>
<title></title>
<test-cases>
<test-case start='1547481439282' status='broken' stop='1547481439460'>
<name>An uncaught error was detected outside of a test</name>
<title>An uncaught error was detected outside of a test</title>
<labels/>
<parameters/>
<steps/>
<attachments/>
<failure>
<message>Cannot read property 'Base' of undefined
This error originated from your test code, not from Cypress.
When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.
Cypress could not associate this error to any specific test.
We dynamically generated a new test to display this failure.</message>
<stack-trace>Uncaught TypeError: Cannot read property 'Base' of undefined
This error originated from your test code, not from Cypress.
When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.
Cypress could not associate this error to any specific test.
We dynamically generated a new test to display this failure.
at Object.<anonymous> (http://localhost:61925/__cypress/tests?p=cypress\integration\Tests\Test.spec.js-289:15125:38)
at Object.98.allure-js-commons (http://localhost:61925/__cypress/tests?p=cypress\integration\Tests\Test.spec.js-289:15201:4)
at o (http://localhost:61925/__cypress/tests?p=cypress\integration\Tests\Test.spec.js-289:1:265)
at http://localhost:61925/__cypress/tests?p=cypress\integration\Tests\Test.spec.js-289:1:316
at Object.40.mocha-allure-reporter (http://localhost:61925/__cypress/tests?p=cypress\integration\Tests\Test.spec.js-289:7566:1)
at o (http://localhost:61925/__cypress/tests?p=cypress\integration\Tests\Test.spec.js-289:1:265)
at r (http://localhost:61925/__cypress/tests?p=cypress\integration\Tests\Test.spec.js-289:1:431)
at http://localhost:61925/__cypress/tests?p=cypress\integration\Tests\Test.spec.js-289:1:460</stack-trace>
</failure>
</test-case>
</test-cases>
</ns2:test-suite>
Please guide me. Thanks!
I was able to use mocha-allure-reporter by simply installing it (along with mocha),
npm install mocha mocha-allure-reporter
and setting up a script in package.json, following the Cypress guidelines for npm reporters here
"scripts": {
...
"cypress:run": "cypress run --reporter mocha-allure-reporter"
Note, I think that these reporters only work with the Cypress 'run' command, not the Cypress 'open' command.
The output is a folder called 'allure-results' which contains a bunch of xml files. I presume these can then be displayed using the Allure framework tool.
Example output file:
<?xml version='1.0'?>
<ns2:test-suite xmlns:ns2='urn:model.allure.qatools.yandex.ru' start='1547254197911' stop='1547254201289'>
<name>Tasks Page</name>
<title>Tasks Page</title>
<test-cases>
<test-case start='1547254199721' status='passed' stop='1547254199815'>
<name>should have a title</name>
<title>should have a title</title>
<labels/>
<parameters/>
<steps/>
<attachments/>
</test-case>
</test-cases>
</ns2:test-suite>
Run allure code in cy.task()
To run the allure code, you need to access the nodejs context through cy.task.
For example,
/cypress/plugins/index.js
require('mocha-allure-reporter');
module.exports = (on) => {
on('task', {
allureTestStep () {
const testStep = allure.createStep("initial", () => {
console.log("First Test")
});
testStep()
return null
}
})
}
spec
describe("simple test demo", () => {
it("simple passed test", () => {
cy.task('allureTestStep')
});
})
Note this produces the console log in the command window where you start Cypress, not the browser console.
However, you can pass a value back from the task into the test, depending on what you are actually trying to do (see docs for details).