How to add images to mochawesome report using Codeceptjs? - node.js

I'm doing E2E Tests on my own and I found really useful node libraries such as CodeceptJS, WebdriverIO and mocha (mochawesome).
Mochawesome permit to add images in the report but in the way that is explained in its docs with addContext https://www.npmjs.com/package/mochawesome doesn't work with CodeceptJS.
I didn't find any reference about this feature used in CodeceptJS, I only found a git request https://github.com/Codeception/CodeceptJS/issues/379
Is there a way to add images to mochawesome reported generated by mocha using CodeceptJS?
I have my file_test.js with one Before, one After and one Scenario.
What I did is const addContext = require('mochawesome/addContext');
and than add the 'addContext(this,imagePath)' function but I get error
[mochawesome] Error adding context: Invalid test object.

I think the this object you're looking for is this.ctx in Codeceptjs.
Try with addContext(this.ctx, imagePath)

Test should look like:
I.addMochawesomeContext('<screenshot path and name here>');
.......test steps
You can find more information about mocha reporting directly on Codeceptjs web-site: http://codecept.io/reports/
Btw. you cannnot add context in Before and After, context should be unique for each scenario.

Related

BeforeEach step is repeated with cy.session using cypress-cucumber-preprocessor

I have a Cypress project where I use the Cypress session API to maintain a session throughout features.
Now I try switching from the deprecated Klaveness Cypress Cucumber Preprocessor to the replacement, Badeball's Cypress Cucumber Preprocessor. But I am running into an issue; the beforeEach() step where my authentication takes place gets repeated several times before the tests start. Eventually, Cypress "snaps out of it" and starts running the actual tests - but obviously this is very resource and time intensive, something is going wrong.
My setup:
Dependencies:
"cypress": "^9.6.1",
"#badeball/cypress-cucumber-preprocessor": "^9.1.3",
index.ts:
beforeEach(() => {
let isAuthInitialized = false;
function spyOnAuthInitialized(window: Window) {
window.addEventListener('react:authIsInitialized', () => {
isAuthInitialized = true;
});
}
login();
cy.visit('/', { onBeforeLoad: spyOnAuthInitialized });
cy.waitUntil(() => isAuthInitialized, { timeout: 30000 });
});
login() function:
export function login() {
cy.session('auth', () => {
cy.authenticate();
});
}
As far as I can see, I follow the docs for cy.session almost literally.
My authenticate command has only application specific steps, it does include a cy.visit('/') - after which my application is redirected to a login service (different domain) and then continues.
The problem
cy.session works OK, it creates a session on the first try - then each subsequent time it logs a succesful restore of a valid session. But this happens a number of times, it seems to get stuck in a loop.
Screenshot:
It looks to me like cy.visit() is somehow triggering the beforeEach() again. Perhaps clearing some session data (localstorage?) that causes my authentication redirect to happen again - or somehow makes Cypress think the test starts fresh. But of course beforeEach() should only happen once per feature.
I am looking at a diff of my code changes, and the only difference except the preprocessor change is:
my .cypress-cucumber-preprocessorrc.json (which I set up according to the docs
typing changes, this preprocessor is stricter about typings
plugins/index.ts file, also set up according to the docs
Am I looking at a bug in the preprocessor? Did I make a mistake? Or something else?
There are two aspects of Cypress + Cucumber with preprocessor that make this potentially confusing
Cypress >10 "Run all specs" behaviour
As demonstrated in Gleb Bahmutov PhD's great blog post, if you don't configure Cypress to do otherwise, running all specs runs each hook before each test. His proposed solution is to not use the "run all specs" button, which I find excessive - because there are ways around this; see below for a working solution with the Cucumber preprocessor.
Note: as of Cypress 10, "run all specs" is no longer supported (for reasons related to this unclarity).
Cucumber preprocessor config
The Cypress Cucumber preprocessor recommends to not use the config option nonGlobalStepDefinitions, but instead configure specific paths like (source):
"stepDefinitions": [
"cypress/integration/[filepath]/**/*.{js,ts}",
"cypress/integration/[filepath].{js,ts}",
"cypress/support/step_definitions/**/*.{js,ts}",
]
}
What it doesn't explicitly state though, is that the file which includes your hooks (in my case index.ts) should be excluded from these paths if you don't want them to run for each test! I could see how one might think this is obvious, but it's easy to accidentally include your hooks' file in this filepath config.
TLDR: If I exclude my index.ts file which includes my hooks from my stepDefinitions config, I can use "run all specs" as intended - with beforeEach() running only once before each test.

Cypress with BDD Cucumber how to create my own data type

I am using cypress with cucumber-js and i need to define my own data type. I did exactly same things like is described in https://github.com/TheBrainFamily/cypress-cucumber-preprocessor#custom-parameter-type-resolves.
That means:
cypress > support > step_definitions > customParameterTypes.js
I wrote:
const blogType = ["sport", "gaming"]
defineParameterType({
name: "blogType",
regexp: new RegExp(blogType.join("|"))
})
and in my BDD .feature file i have:
Given I have empty blog
And Blog has default structure for sport
and in my cypress file:
Given(' Blog has default structure for {blogType}', blogType => {...})
When i start my test i get:
The following error originated from your test code, not from Cypress.
> Undefined parameter type {blogType}
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.
For some reasons, I've had problems using defineParameterType() in the past, and am now using regexp in all my BDD projects.
In your .js file:
Given(/^Blog has default structure for (sport|gaming)$/, blogType => {...});
Using the above, you won't need customParameterTypes.js and your .feature file stays the same.

How can I test the shape of data passed into an Apollo GraphQL query in React Testing Library?

I am following the official doc here: https://www.apollographql.com/docs/react/development-testing/testing/ to create tests for my react component.
However, I can't seem to find a way to test the shape of the data that is passed into the mutation and I am interested in doing so as that ensures that my code will work as expected.
To elaborate. let's say this is what some pseudo code looks like:
const [doMutation] = useMutation(MUTATION)
...
await doMutation({...data})
In my test (jest/react-testing-library), I would like to:
expect(doMutation).toHaveBeenCalledWith({...data});
You can use generated Typescript types that will help. You'll know your GraphQL schema changes when Typescript will begin to yell.
We've done this with the apollo codegen:generate command:
https://www.leighhalliday.com/generating-types-apollo
This helped our frontend team know when the backend schema changed and what needed to be fixed. It was awesome!

JEST Change pre-formatted output from test case

I have an application that runs a Jest test suite from the command line, then takes the JSON output, parses it and then fills table in a database as per the output file. The application runs shell command:
npm run all
and in the package.json file the all script looks like this:
"scripts": {
"all": "../node_modules/.bin/jest --json --outputFile=testResults.json",`
......
}
So I get the testResults.json file and I am able to parse it - so far so good.
But during the test case run I would like to add some extra data to the output. Something like details - where the problems is, how to fix it, some troubleshooting information etc. For example to put one more field in :
require('testResults.json').testResults[x].assertionResults[y].details
You see, the detail property is not part of the json output file format. But can I create it from within the test case (pseudo example):
test('Industry code should match ind_full_code', async () => {
result = await stageDb.query(QUERY);
// And here I want to add this custom information to some global property available?
reporter.thisTestCase.assertionResults.details = "Here is what you should do to fix this ...." // <- Ideally this is how easy I imagine it to be.
expect(result.results).toEqual([]);
}, 2 * 100 * 1000)
I just want to give a little bit more information to the QA or whomever on test failure.
In other words I need the option to change the output from within the test case.
I've been looking into custom reporters, but their listeners are passed the same information as to the json reported.
I've found a need for a similar feature in Jest. The ability to add documentation to the test is rarely supported by test frameworks.
However I found a way to do this with the soon to be default runner: Jest Circus. I then made my own Jest Circus environment. A custom Jest Circus environment provides more test events/lifecycles and access to the actual test code that is being ran.
// Example of a custom Jest Circus environment
export default class MyCustomNodeEnvironment extends NodeEnvironment {
handleTestEvent(event: Circus.Event, state: Circus.State) {
if(event.name === 'test_fn_start') {
console.log(event.test.toString())
// will log the actual test code.
}
}
}
// jest.config.js
{
"testEnvironment": "<rootDir>/my-custom-environment.js",
"testRunner": "jest-circus/runner"
}
I then used regex patterns to find comments in the test functions and add them to the Allure report (Allure report demo).
If you'd like to create your own Jest environment and implement this yourself I've made a template repo or if you prefer a gist of a basic Jest Circus environment.
If you like how Allure reports look you should checkout my open source project jest-circus-allure-environment.

How to disable Jest `console.log` tags

I have some NodeJS logging done via console.log() internally (its actually loglevel) and as I see it, Jest tags console.log output with console.log ../path/to/string/with/console.log/call:line# for whatever reason:
I haven't found any related options in the docs. How can I disable it?
IMPORTANT:
I had the curiosity to take a look to the answer mentioned in the first answer, wich it says:
Looking at the source code for Jest, it doesn't seem like there is a
neat way to turn those messages off.
And I noticed an update marked on the answer and resolves the problem.
Solution:
Just add this code to your test:
beforeEach(() => {
global.console = require('console');
});
Create a global configuration test file e.g. src/test/config.js, add this line to that file:
jest.spyOn(console, "log").mockImplementation();
add this to jest config:
setupFilesAfterEnv: ['./src/test/config.js']
you can also use that file for global cleanup, before/after each etc
Thanks #Anders Carstensen, I've looked at the answer you mentioned and it says:
Looking at the source code for Jest, it doesn't seem like there is a neat way to turn those messages off.
Not an option for me to write my own console, so I'll just stick with Mocha/Sinon for now.
tslalamam answer code not worked for me, but this one works
1: Create a file with this code (e.g. config.js)
import console from "console"
global.console = console
2: Add this line to your jest.config.js
setupFilesAfterEnv: ["./config.js"]
Before:
After:
Enjoi!

Resources