Giter VIP home page Giter VIP logo

cypress-mongodb's Introduction

Introduction

Plugin that allows interaction with MongoDB server using Cypress commands.

Installation

run npm install cypress-mongodb
configure (see below)
profit

Supported and tested system versions

Versions
MongoDB 4.4, 5.0, 6.0
Node 16.20, 18.16, 20.5
MongoDB Node.js Driver 4.10.0

known issues

If you use mongodb dependency in your project, it hast to be version <=4.10.0, otherwise you'll get a Webpack compilation error

Plugin configuration

In your cypress.config.js file, make the following changes:

  1. Add the necessary mongodb environment variables under env block
  2. Import and load the plugin under e2e block
import { configurePlugin } from 'cypress-mongodb';

module.exports = defineConfig({
    env: {
        mongodb: {
            uri: 'mongodb://localhost:27017',
            database: 'database_name',
            collection: 'collection_name'
        }
    },
    e2e: {
        setupNodeEvents(on, config) {
            configurePlugin(on);
        }
    }
});

Note: only mongodb.uri is mandatory, you can always override/set database and collection names in each cypress mongodb command using options. You can set both local and remote urls.

Finally, in your cypress/support/e2e.js add the following:

import { addCommands } from 'cypress-mongodb/dist/index-browser';
addCommands();

Documentation

Collection commands

> syntax

cy.createCollection(name);
cy.createCollection(name, options);

cy.dropCollection(name);
cy.dropCollection(name, options);

> arguments

Arguments Type Description
name String (required) Name of the collection to create/drop
options Object (optional) Provide additional options (see below)

> examples

cy.createCollection('someCollection'); // collection with name `someCollection` will be created

cy.createCollection('someOtherCollection', { database: 'someDatabase', failSilently: 'true' }).then(result => {
    cy.log(result); // Will return 'Collection created' or the error object if collection already exists. Will not fail the test
});

cy.dropCollection('someCollection'); // collection will be droped

cy.dropCollection('nonexistentCollection', { database: 'someDatabase', failSilently: 'true' }).then(result => {
    cy.log(result); // Will return 'Collection dropped' or the error object if collection doesn’t exist. Will not fail the test
});

Insert commands

> syntax

cy.insertOne(document);
cy.insertOne(document, options);

cy.insertMany(documents);
cy.insertMany(documents, options);

> arguments

Arguments Type Description
document Object (required) A Document object that will be inserted
documents Object[] (required) An array of Document objects that will be inserted
options Object (optional) Provide additional options (see below)

> examples

cy.insertOne({document: 1}); // will insert the provided document in mongodb

cy.insertOne({document: 1}, {collection: 'someCollection', database: 'someDatabase'}).then(result => {
    cy.log(result); // prints the _id of inserted document
});

cy.insertMany([{document: 1}, {document: 2}]); // will insert provided documents in mongodb

cy.insertMany([{document: 1}, {document: 2}], {collection: 'some_other_collection'}).then(result => {
    console.log(result); // prints the key-value pairs of the inserted ids
});

Find commands

> syntax

cy.findOne(query);
cy.findOne(query, options);

cy.findMany(query);
cy.findMany(query, options);

cy.findOneAndUpdate(filter);
cy.findOneAndUpdate(filter, options);

cy.findOneAndDelete(filter);
cy.findOneAndDelete(filter, options);

> arguments

Arguments Type Description
query Object (required) Specifies query selection criteria using query operators
filter Object (required) The selection criteria for the deletion
options Object (optional) Provide additional options (see below)

> examples

import { ObjectId } from 'mongodb';
cy.findOne({_id: new ObjectId()}).then(result => {
    cy.log(result); // prints the document with the _id if found, otherwise null
});

cy.findMany({document: 1}).then(result => {
    cy.log(result); // prints the array of documents if any matched, or empty array
});

cy.findOneAndUpdate({ document: 2 }, { $set: { document: 3 }}).then(result => {
  cy.log(result); // prints the original document with value 2
});
cy.findOneAndUpdate({ document: 3 }, { $set: { document: 4 }}, {upsert: true, returnDocument: 'after'}).then((result: any) => {
  cy.log(result); // prints the updated document with the value 4, will create (upsert) a new document if none are found
});

Update commands

> syntax

cy.updateOne(filter, update);
cy.updateOne(filter, update, options);

cy.updateMany(filter, update);
cy.updateMany(filter, update, options);

> arguments

Arguments Type Description
filter Object (required) The selection criteria for the update
update Object or pipeline (required) The modifications to apply
options Object (optional) Provide additional options (see below)

> examples

cy.updateOne({document: 1}, { $set: { document: 2 } }, { upsert: true }).then(result => {
    cy.log(result); // prints the object containing the update info: matchedCount, modifiedCount, upsertedCount, etc
});

cy.updateMany({document: 1}, { $set: { document: 2 } }, { upsert: true }).then(result => {
    cy.log(result); // prints the object containing the update info: matchedCount, modifiedCount, upsertedCount, etc
});

Delete commands

> syntax

cy.deleteOne(filter);
cy.deleteOne(filter, options);

cy.deleteMany(filter);
cy.deleteMany(filter, options);

> arguments

Arguments Type Description
filter Object (required) Specifies deletion criteria using query operators
options Object (optional) Provide additional options (see below)

> examples

cy.deleteOne({document: 1}); // will delete a first matched document

cy.deleteOne({document: 1}, {collection: 'new_collection', database: 'some_database'}).then(result => {
    cy.log(result); // prints 1 (or 0) document deleted
});

cy.deleteMany(deleteClause).then(res => {
    cy.log(result); // prints '# documents deleted'
});

Aggregate commands

> syntax

cy.aggregate(pipeline);
cy.aggregate(pipeline, options);

> arguments

Arguments Type Description
pipeline Object[] (required) An array of object representing a sequence of data aggregation operations or stages
options Object (optional) Provide additional options (see below)

> examples

const pipeline = []; // any kind of aggregation
cy.aggregate(pipeline).then(result => {
    cy.log(result); // prints the result of the aggregation
});

runCommand

> syntax

cy.runCommand(command);
cy.runCommand(command, options);

> arguments

Arguments Type Description
command Document (required) A document representing the mongodb command to run
options Object (optional) Provide additional options (see below)

> examples

const command = { listCollections: 1, nameOnly: true }; // any kind of command
cy.runCommand(command).then(result => {
    cy.log(result); // prints the result of the command
});

> available options

Options Default Description
database Value specified in the mongodb environment variable Database on top of which the command will be executed
collection Value specified in the mongodb environment variable Collection on top of which the command will be executed
failSilently false Control if the command will fail or if the collection is not found
createCollection options N/A Refer to official documentation
dropCollection options N/A Refer to official documentation
insertOne options N/A Refer to official documentation
insertMany options N/A Refer to official documentation
findOne options N/A Refer to official documentation
findMany options N/A Refer to official documentation
findOneAndUpdate options N/A Refer to official documentation
findOneAndDelete options N/A Refer to official documentation
updateOne options N/A Refer to official documentation
updateMany options N/A Refer to official documentation
deleteOne options N/A Refer to official documentation
deleteMany options N/A Refer to official documentation
aggregate options N/A Refer to official documentation

Reference

https://mongodb.github.io/node-mongodb-native/6.0/

Future development & support

Please create feature requests for things you'd like to see.
Please raise issues for any problems you encounter.

cypress-mongodb's People

Contributors

zaista avatar ajhoddinott avatar edgerunner avatar pabloramirezdev avatar

Stargazers

Kallef Alexandre avatar Ana avatar Luke Harrison avatar Yubram Ferreira Guevara avatar Jonatan Asketorp avatar Aziz Nal avatar Mirlanda Costa avatar  avatar Hemal avatar Matthieu Vion avatar  avatar Raí Almeida avatar Christian avatar  avatar  avatar  avatar  avatar

Watchers

Jonatan Asketorp avatar  avatar

cypress-mongodb's Issues

Authentication fails when not adding database name at the end of uri

Hi,

I have an issue when passing a password with a character '?' needing to be percent encoded (as specified in https://www.mongodb.com/docs/manual/reference/connection-string/)

When using this in cypress.config.ts with escaped '?'

mongodb: {        
	uri: 'mongodb://myLogin:passwd%[email protected]',
        database: 'mydatabase',
        collection: 'mycollection',
      },

I get error authentication failed when using cy.mindMany

Screenshot 2023-05-17 at 10 08 49

When using this in cypress.config.ts with unescaped '?'

      mongodb: {
        uri: 'mongodb://myLogin:[email protected]',
        database: 'mydatabase',
        collection: 'mycollection',
      },

I get error Password contains unescaped characters when using cy.mindMany

Screenshot 2023-05-17 at 10 12 18

I can connect to the mongodb using Studio 3T with no problem:
Screenshot 2023-05-17 at 10 20 28

Environment:

  • Cypress: 12.8.1
  • cypress-mongodb: 5.3.0
  • TypeScript: 4.9.5
  • mongoDB: 5.0.6

Is escaping of chars in password supported?
Thx

insertOne command returns wrong error

The insertOne command throws the error Pipeline must be an object, although it doesn't receive any pipeline parameter.

Checked the source code and could solve it changing args.pipeline by args.document in the insertOne util.

Unable to use deleteOne with _id

When attempting to use deleteOne with _id it does not work for me but when I use other key/values I can get it to delete. I dont know what I am doing wrong. I can use another mongo package and delete by _id and new ObjectId('634d732c5bcba068900dfc94'). I am using import { ObjectId } from 'mongodb';

This code works:
const filter = { 'merchant': 1234, 'isActive': true } const options = { collection: 'Locations' } cy.deleteOne(filter, options).then((results: any) => { cy.log('results', results) // Yielded: 1 document deleted })

This code fails:
const filter = { _id: new ObjectId('634d732c5bcba068900dfc94') } const options = { collection: 'Locations' } cy.deleteOne(filter, options).then((results: any) => { cy.log('results', results) // Yielded: 0 document deleted })

Could not resolve "crypto" and others (trying to use it with a preprocessor )

image

This is my e2e.js file

import './commands';
import './StepDefinition/Global';
import 'cypress-mochawesome-reporter/register';
import 'cypress-xpath';
import { addCommands } from 'cypress-mongodb/dist/index-browser';
addCommands();

This is cypress config file

const addCucumberPreprocessorPlugin =
require('@badeball/cypress-cucumber-preprocessor').addCucumberPreprocessorPlugin;
const createEsbuildPlugin =
require('@badeball/cypress-cucumber-preprocessor/esbuild').createEsbuildPlugin;
const cypressmongodb = require('cypress-mongodb');

module.exports = defineConfig({
env: {
mongodb: {
uri: '',
database: 'database_name',
collection: 'collection_name'
}
},
setupNodeEvents(on, config) {
cypressmongodb.configurePlugin(on);
require('cypress-mochawesome-reporter/plugin')(on);
}
});

mongodb_stepdef.js

import { When, Given, Then } from '@badeball/cypress-cucumber-preprocessor';
const collection_data = {

uri: '',
database: '',
collection: ''
}
Given('It Should create new collections', () => {
//create collection
cy.createCollection(collection_data.collection).then((result) => {
assert.strictEqual(result, 'Collection created');
});
});

mongodb.feature
Feature: Testing MongoDB Integration with Cypress

Scenario: Insert data into MongoDB
Given It Should create new collections

Package.json
"dependencies": {
"@badeball/cypress-cucumber-preprocessor": "latest",
"@bahmutov/cypress-esbuild-preprocessor": "2.1.5",
"@faker-js/faker": "^8.0.2",
"@percy/cypress": "^3.1.2",
"cypress": "^13.8.0",
"cypress-mochawesome-reporter": "^3.2.2",
"cypress-mongodb": "^6.2.0",
"cypress-xpath": "^2.0.1",
"dotenv": "^16.0.1",
"esbuild": "^0.15.9",
"fast-csv": "^4.3.6",
"install": "^0.13.0",
"mongodb": "3.6.6",
"xlsx": "^0.18.5"
},
"cypress-cucumber-preprocessor": {
"stepDefinitions": "cypress/e2e/**//.{js,ts}",
},
"devDependencies": {
"cypress-multi-reporters": "^1.6.3",
"cypress-v10-preserve-cookie": "^1.2.1"
}
}

ObjectId type is not working

Great library, the API is simple and I'm thankful for TypeScript support.

The Problem

I want to hard code the _id on an inserted user. When I pass the

import { ObjectId } from "MongoDB";

describe("login", () => {
  beforeEach(() => {
    cy.deleteMany({}, "users");
    const objectId = new ObjectId();

    const user = {
      _id: objectId,
      ...otherFields
    };

    cy.insertOne(user, "users").then((res) => {
      cy.log(JSON.stringify(res));
    });

When I run this, the objectId is inserted as a string on the mongoDb model (see Compass screenshot below).

Screen Shot 2022-03-10 at 1 07 23 PM

If I remove the _id field in the payload, the system is able to autogenerate a valid ObjectId on the mongo entry.

Screen Shot 2022-03-10 at 1 06 36 PM

What's going on? Why is the ObjectId object being converted to a string on the insert?

I looked into the forceServerObjectId on the insert options but haven't had any success figuring it out.

Could not resolve "crypto" and others (trying to use it with a preprocessor )

I'm trying to use that with cucumber preprocessor but it doesn't recognize the commands

image

and in terminal
image

i have this in my e2e config file

e2e: {
    reporter: require.resolve("@badeball/cypress-cucumber-preprocessor/pretty-reporter"),
    // We've imported your old cypress plugins here.
    // You may want to clean this up later by importing these.
    setupNodeEvents( cypressOn, config ) {
         const on = require('cypress-on-fix')(cypressOn);

      // This is required for the preprocessor to be able to generate JSON reports after each run, and more,
      addCucumberPreprocessorPlugin(on, config);

      on(
        "file:preprocessor",
        createBundler({
          plugins: [createEsbuildPlugin(config)],
        })
      );
      configurePlugin(on)

      return config;

    }

any way to use it? thx)

How to use specific property names

Hi,

According to documentation, we need to configure mongodb access with this pattern (in cypress.config.ts):

{
    module.exports = defineConfig({
        env: {
            mongodb: {
                uri: "mongodb://login:password@url",
                database: "database_name",
                collection: "collection_name"
            }
        }
    });
}

What if I want/need to use these properties which are set by CI when launching tests?

    env: {
      MONGODB_SERVER: '<url>',
      MONGODB_BASE: '<database_name>',
      MONGODB_LOGIN: '<login>',
      MONGODB_PASS: 'passW0rd',
      MONGO_COLLECTION: 'collection',

=>

      mongodb: {
        uri: 'mongodb://MONGODB_LOGIN:MONGODB_PASS@MONGODB_SERVER',
        database: 'MONGODB_BASE',
        collection: 'MONGO_COLLECTION',
      },

Thanks for your help!

Error: Webpack Compilation Error when we set const mongo = require('cypress-mongodb'); mongo.addCommands();

As per your provided configuration, When we added the below lines and run our spec file we got this error.

In your cypress/support/e2e.js add the following:
const mongo = require('cypress-mongodb');
mongo.addCommands();

Spec file snapshot attahced for refernece.

image

Error snapshot is attached for reference.
image
Pakage,json
{ "name": "cypress", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "cypress": "^10.9.0", "cypress-downloadfile": "^1.2.3", "npm-check-updates": "^16.3.11" }, "devDependencies": { "cypress-file-upload": "^5.0.8", "cypress-mochawesome-reporter": "^3.2.3", "cypress-xpath": "^2.0.1", "multiple-cucumber-html-reporter": "^3.0.1" } }

Returns data changed when updating or deleting files in result

Hello,

Currently does not return changed or deleted data from a collection in the result

In version 5.2 of mongo, it is possible to use the function findOneAndUpdate() or findOneAndDelete passing as option returnDocument 'after' or 'before' to return the changed or deleted result.

It's cool any mongoDB command has the option to return the result in the console.

Note: I noticed that apparently there is a conflict when updating to a new version of mongoDB

filter doesn't seem to work for findOne or updateOne

This doesn't work. "Item" is defined earlier in the document.

    const filter = {
      name: item.name
      slug: item.slug,
      url: item.url
    };
    const document = { $set: { 
      category: item.category,
      image: item.image,
      url: item.url,
      price: item.price
    } };
    const options = {"collection": "coll", "database": "db"} 
    cy.updateOne(filter, document, options).then((res) => {
      cy.log("update attempted", res)
   })

It doesn't seem possible to use a filter in either the findOne or updateOne methods. The only method I can get to work is insertOne with all the same values above only without the filter.

Couldn't find any documentation on querying data

Hi! I'm working on a cypress & typescript project. I have installed cypress-mongodb and it's great.
However, I struggled to find references on how to do things properly (examples of good practices).

For instance, I ended up doing something like this:

cy.findMany(
      { email: "[email protected]" },
      { collection: "users" }
    ).should((result: any) => {
      expect(result?.length).to.equal(1);
      const firstElement = result[0];
      expect(firstElement.email).to.equal("[email protected]");
      expect(firstElement.firstName).to.equal("Norberto");
      expect(firstElement.lastName).to.equal("Herz");
      expect(firstElement.provider).to.equal("password");
      expect(firstElement).not.to.have.property("password");
    });

Do you think this approach is correct?
Is there any better option than typing result as any?
Do you know if I am supposed to use then/should and that list of expects inside?

I got that working after hours of searching, not founding documentation, and trial and error.

P.S.: I'd love to start writing some docs once I have a clear idea of what I'm doing.

Inserting a date as an object vs a string

Hi,

First up, thanks for the super useful package, it has helped a lot!

Kind of a silly question (please let me know if this is not the right place to ask).


For a document to be added:

const document = {
  text: 'whatever'
  createdAt: new Date()
}

From my normal application (a Meteor application), inserting this results in a createdAt field that is of a Date type. However, doing the same within cypress:

cy.insertOne({
  text: 'whatever'
  createdAt: new Date()
});

... leads to a document where the createdAt field is of type string.

Is there something straightforward that I am missing? I have tried looking around but all documentation and queries regarding this seem to indicate that mongo should be automatically defaulting to an object type.

Thanks in advance!

filtering documents using _id with UUID does not work

Looks like filtering documents using _id with UUID does not work.

cypress-mongodb version: 5.1.2
mongo version: 4.4
collection is sharded

Example with findOne but it fails with ie. findOne > deleteOne too:

const { UUID } = require('bson');
it('nested findOne number > ID UUID', () => {
    cy.findOne({ queryNo: 12345678 }, { collection: 'collection' }).then(res => { // works
      // const ID = res['_id']
      const ID = JSON.stringify(res['_id']) // fbebd5d8-2b0c-43ef-8f08-9060747b751b
      cy.findOne({ _id: UUID(ID) }, { collection: 'collection' }).then(res => { // does not work
        console.log(JSON.stringify(res), 'nested findOne number > _id')
      })
    });
  })

Any thoughts/solutions?

Insert One Document always returns a duplicated default set of data

Hi,

I'm using the Insert One method to insert data into my db, however it always returns my data as an object plus with an default set like the following:

-object()
--data
-default
---object
----data

I am unclear as to why its seeding my data in this form but is there anyway to just store it without either objects or defaults and just the data itself??

Appreciate the help, thanks!

Lisa

No change option?

The mongo update command is missing.

The option to edit a data in the collection was missing.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.