Skip to content

FactoryBot.create() for Cypress UI tests

License

Notifications You must be signed in to change notification settings

Splines/cypress-rails-factory-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 

Repository files navigation

Decorating header image

Cypress ❤ FactoryBot (Ruby on Rails)

A blog post / demo for how to use FactoryBot, the DatabaseCleaner and programmatic login in Cypress with Ruby on Rails. This is not a library as it's easy enough to copy and paste the few lines of code into your own project without any additional dependencies. Here's how a Cypress test might look like in the end (see it here for a commented version)

How your Cypress tests can look like:

// spec/cypress/e2e/submissions_spec.cy.js
import FactoryBot from "../support/factorybot";

describe("Submissions", () => {
  beforeEach(() => {
    cy.cleanDatabase();
    cy.createUserAndLogin("generic");
  });

  it("can create a submission", function () {
    FactoryBot.create("assignment", "with_deadline_tomorrow", { file_type: ".pdf", size_max: 10 })
      .as("assignment");

    cy.then(() => {
      console.log(this.assignment);
    });
  });
});

💡 Motivation

Testing tools should work for, not against you. And Cypress for sure works for you; it's a great UI testing framework. In order to setup reliable test, you should test specs in isolation, i.e. tests should not depend on each other. This includes cleaning the database before each test run and creating mock data. For Rails tests, we have the great FactoryBot that helps us with this. And there's also a DatabaseCleaner to ensure a clean state for tests.

But how can we use these tools in Cypress, a frontend tool that doesn't have access to the database?

cypress-on-rails?

We've been using cypress-on-rails to achieve this so far and it works. However, we didn't like the interface as it was so different from what we were used to in RSpec. It also requires you to set up associations manually, which is a bit of a pain. So, we decided to write our own solution, and it turns out that it's really not that hard to get it up and running.

🌟 Solution

This solution is inspired by this great blog post by Tom Conroy. You can find all necessary files inside the demo/ folder, feel free to use them in your own project (you don't have to, but you can link back to this repo to let others know about it). Here's an overview of what we do. Follow these steps to apply it to your own project. The individual files are commented and should be self-explanatory.

  • Set up custom Rails routes (only available in the Rails test environment) with respective controllers that execute the backend code, e.g. call the FactoryBot, use the DatabaseCleaner or create a new user (or anything you like). The cypress_controller.rb is the base class that the other controllers inherit from. It's just there to ensure errors are sent back to the frontend, such that you can see them in Cypress in the test browser.
  • Implement a JS interface for Cypress that allows to call these routes from the Cypress test and provide nice error logging in case anything goes wrong.
  • That's basically it. Now you can define custom Cypress commands in Cypress or even your own JS classes, e.g. the FactoryBot wrapper. Import it via import FactoryBot from "../support/factorybot"; and you're ready to use FactoryBot.create("...") in your Cypress tests as shown above.

This solution is easily extendable. Add more controllers, routes and custom Cypress commands as you see fit.