In this tutorial let’s see how you can get data from MongoDB and use the data when you test APIs with Cypress framework. Getting data from a database is not straightforward in Cypress as it basically runs the tests in a browser.
Cypress allows to run backend node.js code in a separate files called plugins.
A typical cypress project structure looks like the above. Under the plugins folder you can create a file called index.js which runs in the backend as a node.js code, which can be used to retrieve data from a database.
But where would you keep the data that you have read from the database? That’s where fixtures come in. You can have your data as json files under fixtures directory and use it in your code for testing.
To summarize, I’m going to read data from mongo using Cypress tasks and write the json files under fixtures directory and use the data for testing.
My index.js file under plugins would look like this.
/// <reference types="cypress" /> // *********************************************************** // This example plugins/index.js can be used to load plugins // // You can change the location of this file or turn off loading // the plugins file with the 'pluginsFile' configuration option. // // You can read more here: // https://on.cypress.io/plugins-guide // *********************************************************** // This function is called when a project is opened or re-opened (e.g. due to // the project's config changing) /** * @type {Cypress.PluginConfig} */ const MongoClient = require('mongodb').MongoClient; fs = require('fs') module.exports = (on, config) => { on('task', { getData({ collection, filter }) { return new Promise((resolve) => { MongoClient.connect('mongodb://username:password@localhost:27017', (err, client) => { if (err) { console.log(`MONGO CONNECTION ERROR: ${err}`) throw err; } else { const db = client.db('my_db'); console.log("Collection --- " + collection + " --- filter --- " + JSON.stringify(filter)); let i = 0; try { fs.unlinkSync('cypress/fixtures/responses.json'); } catch (err) { console.log("Error while deleting the responses.json file." + err); } db.collection(collection).find({ key:filter }).toArray(function (error, docs) { if (error) { console.log("Error while fetching documents from collection."); return; } console.log(docs); docs = docs.reduce((docs, e) => ({ ...docs, [e.key]: e }), {}); fs.appendFile('cypress/fixtures/responses.json', JSON.stringify(docs), 'utf8', function (err) { if (err) throw err; console.log("Data is appended to file successfully.") resolve(''); client.close(); }); }) } }) }); } }) };
In your before method, you can use cy.task to call this plugin.
before(() => { cy.task('getData', { collection: 'api_responses', filter: "api" }); })
This cy.task is synchronous, you can also use callbacks for more.
before(() => { cy.task('getData', { collection: 'api_responses', filter: "api" }).then((result) = { console.log("Data retrieved from Mongo and written to fixtures"; }; })
Once this before block is executed, you can see a new file created under fixtures, called responses.json.
You can read this file using cy.fixtures in your tests.
cy.fixture('responses.json').then((responses) => { }