cypress: .should('deep.equal') does not show a full diff comparison on failures

Current behavior:

Cypress does not show enough information to know what is the difference when deep comparing complex objects.

Example:

cy
  .wrap({ foo1: { bar: { foo1: { bar: 1 } } }, foo2: { bar: 1 } })
  .should('deep.equal', { foo1: { bar: { foo1: { bar: 1 } } }, foo2: { bar: 2 } })

Result:

Screen Shot 2019-04-30 at 10 29 33 PM

Desired behavior:

Ideally, I’d like cypress to show a complete diff of the compared objects so we can easily spot the difference.

Versions

cypress@3.2.0

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 32
  • Comments: 24 (2 by maintainers)

Most upvoted comments

Showing a more detailed diff of objects in the error message is part of this larger issue, that is currently in progress: https://github.com/cypress-io/cypress/issues/3762 You can see an comment on our planned designs there.

Will leave this open as part of that epic.

You can also click on the Assert command in the Command Log to see a fully diff within your DevTools console.

@braveheart55 @tsvetan-ganev @gurudattgd04 If you are interested, here is a work-around that a friend of mine (@Bushwazi) came up with that we are using:

In our /support/index.js: we intercept and override our chai expect(expected).to.deep.equal(actual) lines across all of our tests

import { diff } from 'json-diff';

/*
 * Wraps/overwrites the "equal" method so that we can pretty print the diff
 * during errors only.
 *
 * The diffing library adds a "~" JSON key when looking at arrays, but it
 * doesn't affect anything else.
 */
chai.use(function (_chai, utils) {
  utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {
    return function newEqual(str) {
      let obj = utils.flag(this, 'object');
      // "equal" has a "deep" flag it "deep" precedes it
      let deep = utils.flag(this, 'deep');

      try {
        _super.apply(this, arguments);
      } catch (error) {
        // If we do not have the "deep" flag, just throw the standard error
        if (deep !== true) {
          throw(error);
        }

        // If we do have the "deep" flag, use the diff module for highlight the diff
        // and then tidy it up a bit
        let diffObject = "expect objects to match:\n";
        diffObject += JSON.stringify(diff(str, obj), null, 4)
          .replace(/__old/g, "-")
          .replace(/__new/g, "+");
        throw(diffObject);
      }
    }
  });
});

Notes

  • This only gets printed during an assertion failure.
  • This uses this JSON diff library: https://www.npmjs.com/package/json-diff
  • You can get a prettier diff (colorized) if you use console.log() and check the console instead of in-line printing it in the test runner as well.

It will look like this:

image

I’ve also been following this issue for 3 years+.

I understand Cypress is geared more towards UI-testing than API-testing (For example, I don’t need a ViewPort if I’m just testing a JSON REST API, yet there is no flag to turn this off), but they really should start adding some quality of life changes for API-only testing.

It would be great if there was an API_ONLY_TESTING flag or something similar. I bet they can turn off a bunch of UI-only functionality – and improve Cypress performance and responsiveness if you are just testing a REST API.

I’ve just released a plugin that highlights the difference. Simple installation and usage:

https://github.com/elaichenkov/cypress-diff

npm i -D cypress-diff
// cypress/support/e2e.ts
import 'cypress-diff';

Result: image

Feel free to open an issue with improvements. Also, don’t forget to give it a star.

@jennifer-shehane, is there a technical reason why the two objects aren’t diffed? It’s a basic feature for most assertion libraries/test runners. Also I see that the related issue is closed, but this problem still exists in 2022. Are there any ways I can hook into the AssertionError and manually produce a diff from the two objects?

I just had a look at this jsondiffpatch library and realized that the live demo is pretty impressive in terms of diff visuals. Perhaps this could be a possible direction for Cypress especially in the visual GUI runner. https://github.com/benjamine/jsondiffpatch

Thank you Jenniver, Happy to know this is a work in progress! Thanks also for the console tips, very useful!