How to use matchDeepCypress method in Cypress

Best JavaScript code snippet using cypress

snapshotCommand.js

Source:snapshotCommand.js Github

copy

Full Screen

1const _ = require('lodash')2// if we're in Cypress, we'll need to swap this with Cypress.sinon later3let sinon = require('sinon')4const Debug = require('debug')5const chalk = require('chalk')6const stripAnsi = require('strip-ansi')7const { stripIndent } = require('common-tags')8const { printVar, stringifyShort, isObject, addPluginButton, fmt, typeColors } = require('./snapshotUtils')9const debug = Debug('plugin:snapshot')10/**11 * prints nice assertion error in command log with modified error message12 */13function throwErr (e, message, exp, ctx) {14  try {15    ctx.assert(false, message, 'sdf', exp, e.act, true)16  } catch (err) {17    err.message += `\n\n**- expected  + actual:**\n${e.message}`18    throw err19  }20}21function getMatchDeepMessage (act, exp) {22  return `Expected **${chai.util.objDisplay(act)}** to deep match: **${chai.util.objDisplay(exp)}**`23}24function saveSnapshot (ctx, exactSpecName, file, exp, act) {25  const message = !exp ? 'new snapshot saved' : 'snapshot updated'26  ctx.assert(true, `📸 ${message}: **${exactSpecName}**`, '', exp, act)27  return cy.task('saveSnapshot', {28    file,29    what: act,30    exactSpecName,31  }, { log: false })32}33const registerInCypress = () => {34  // need to use correct sinon version for matcher.isMatcher to work35  sinon = Cypress.sinon36  const $ = Cypress.$37  let snapshotIndex = {}38  chai = window.chai39  chai.Assertion.addMethod('matchDeep', matchDeepCypress)40  chai.Assertion.addMethod('matchSnapshot', matchSnapshotCypress)41  after(() => {42    snapshotIndex = {}43  })44  before(() => {45    addPluginButton($, 'toggle-snapshot-update', '', {46      render () {47        const btnIcon = $(this).children().first()48        return btnIcon.text(top.SNAPSHOT_UPDATE ? 'snapshot\nupdate\non' : 'snapshot\nupdate\noff')49        .css({ 'font-size': '10px', 'line-height': '0.9' })50        .html(btnIcon.html().replace(/\n/g, '<br/>'))51      },52      click () {53        top.SNAPSHOT_UPDATE = !top.SNAPSHOT_UPDATE54      },55    })56  })57  function matchDeepCypress (...args) {58    const exp = args[1] || args[0]59    const ctx = this60    try {61      const res = matchDeep.apply(this, [args[0], args[1], { Cypress, expectedOnly: true }])62      const message = getMatchDeepMessage(res.act, exp)63      ctx.assert(true, message)64      Cypress.log({65        name: 'assert',66        message,67        state: 'passed',68        consoleProps: () => {69          return {70            Actual: res.act,71          }72        },73      })74    } catch (e) {75      throwErr(76        e,77        getMatchDeepMessage(e.act, args[1] || args[0]),78        exp,79        ctx,80      )81    }82  }83  function matchSnapshotCypress (m, snapshotName) {84    const ctx = this85    const file = Cypress.spec.name86    const testName = Cypress.mocha.getRunner().test.fullTitle()87    return cy.then(() => {88      snapshotIndex[testName] = (snapshotIndex[testName] || 1)89      const exactSpecName = snapshotName || `${testName} #${snapshotIndex[testName]}`90      return cy.task('getSnapshot', {91        file,92        exactSpecName,93      }, { log: false })94      .then(function (exp) {95        try {96          snapshotIndex[testName] = snapshotIndex[testName] + 197          const res = matchDeep.call(ctx, m, exp, { message: 'to match snapshot', Cypress, isSnapshot: true, sinon })98          ctx.assert(true, `snapshot matched: **${exactSpecName}**`, res.act)99        } catch (e) {100          if (!e.known) {101            throw e102          }103          // save snapshot if env var or no previously saved snapshot (and no failed matcher assertions)104          if ((top.SNAPSHOT_UPDATE || !exp) && !e.failedMatcher && e.act) {105            return saveSnapshot(ctx, exactSpecName, file, exp, e.act)106          }107          throwErr(e, `**snapshot failed to match**: ${exactSpecName}`, exp, ctx)108        }109      })110    })111  }112}113const matcherStringToObj = (mes) => {114  const res = mes.replace(/typeOf\("(\w+)"\)/, '$1')115  const ret = {}116  ret.toString = () => {117    return `${res}`118  }119  ret.toJSON = () => {120    return `match.${res}`121  }122  return ret123}124const matchDeep = function (matchers, exp, optsArg) {125  let m = matchers126  if (exp === undefined) {127    exp = m128    m = {}129  }130  const opts = _.defaults(optsArg, {131    message: 'to match',132    Cypress: false,133    diff: true,134    expectedOnly: false,135    sinon: null,136  })137  if (!opts.sinon) {138    opts.sinon = sinon139  }140  const match = opts.sinon.match141  const isAnsi = !opts.Cypress142  const act = this._obj143  m = _.map(m, (val, key) => {144    return [key.split('.'), val]145  })146  const diffStr = withMatchers(m, match, opts.expectedOnly)(exp, act)147  if (diffStr.changed) {148    let e = _.extend(new Error(), { known: true, act: diffStr.act, failedMatcher: diffStr.opts.failedMatcher })149    e.message = isAnsi ? `\n${diffStr.text}` : stripAnsi(diffStr.text)150    if (_.isString(act)) {151      e.message = `\n${stripIndent`152        SnapshotError: Failed to match snapshot153        Expected:\n---\n${printVar(exp)}\n---154        Actual:\n---\n${printVar(diffStr.act)}\n---155        `}`156    }157    throw e158  }159  return diffStr160}161const parseMatcherFromString = (matcher) => {162  const regex = /match\.(.*)/163  if (_.isString(matcher)) {164    const parsed = regex.exec(matcher)165    if (parsed) {166      return parsed[1]167    }168  }169}170function parseMatcherFromObj (obj, match) {171  if (match.isMatcher(obj)) {172    return obj173  }174  const objStr = (_.isString(obj) && obj) || (obj && obj.toJSON && obj.toJSON())175  if (objStr) {176    const parsed = parseMatcherFromString(objStr)177    if (parsed) {178      return match[parsed]179    }180  }181  return obj182}183function setReplacement (act, val, path) {184  if (_.isFunction(val)) {185    return val(act, path)186  }187  return val188}189const withMatchers = (matchers, match, expectedOnly = false) => {190  const getReplacementFor = (path = [], m) => {191    for (let rep of m) {192      const wildCards = _.keys(_.pickBy(rep[0], (value) => {193        return value === '*'194      }))195      const _path = _.map(path, (value, key) => {196        if (_.includes(wildCards, `${key}`)) {197          return '*'198        }199        return value200      })201      const matched = _path.join('.').endsWith(rep[0].join('.'))202      if (matched) {203        return rep[1]204      }205    }206    return NO_REPLACEMENT207  }208  const testValue = (matcher, value) => {209    if (matcher.test(value)) {210      return true211    }212    return false213  }214  const NO_REPLACEMENT = {}215  /**216   * diffing function that produces human-readable diff output.217   * unfortunately it is also unreadable code in itself.218   */219  const diff = (exp, act, path = ['^'], optsArg) => {220    const opts = _.defaults({}, optsArg, {221      expectedOnly,222    })223    if (path.length > 15) {224      throw new Error(`exceeded max depth on ${path.slice(0, 4)} ... ${path.slice(-4)}`)225    }226    let text = ''227    let changed = false228    let itemDiff229    let keys230    let subOutput = ''231    let replacement = getReplacementFor(path, matchers)232    if (replacement !== NO_REPLACEMENT) {233      if (match.isMatcher(replacement)) {234        if (testValue(replacement, act)) {235          act = matcherStringToObj(replacement.message).toJSON()236        } else {237          opts.failedMatcher = true238          if (!_.isFunction(act)) {239            act = _.clone(act)240          }241          exp = replacement242        }243      } else {244        act = setReplacement(act, replacement, path)245      }246    } else {247      if (!_.isFunction(act) && !_.isFunction(_.get(act, 'toJSON'))) {248        act = _.clone(act)249      }250      exp = parseMatcherFromObj(exp, match)251      if (match.isMatcher(exp)) {252        if (testValue(exp, act)) {253          act = matcherStringToObj(exp.message).toJSON()254          return {255            text: '',256            changed: false,257            act,258          }259        }260        return {261          text: fmt.wrap('failed', `${chalk.green(printVar(act))} ⛔  ${matcherStringToObj(exp.message).toJSON()}`),262          changed: true,263          act,264        }265      }266    }267    if (_.isFunction(_.get(act, 'toJSON'))) {268      act = act.toJSON()269    }270    if (isObject(exp) && isObject(act) && !match.isMatcher(exp)) {271      keys = _.keysIn(exp)272      let actObj = _.extend({}, act)273      let key274      if (_.isArray(exp)) {275        keys.sort((a, b) => +a - +b)276      } else {277        keys.sort()278      }279      for (let i = 0; i < keys.length; i++) {280        key = keys[i]281        const isUndef = exp[key] === undefined282        if (_.hasIn(act, key) || isUndef) {283          itemDiff = diff(exp[key], act[key], path.concat([key]))284          _.defaults(opts, itemDiff.opts)285          act[key] = itemDiff.act286          if (itemDiff.changed) {287            subOutput += fmt.keyChanged(key, itemDiff.text)288            changed = true289          }290        } else {291          subOutput += fmt.keyRemoved(key, exp[key])292          changed = true293        }294        delete actObj[key]295      }296      let addedKeys = _.keysIn(actObj)297      if (!opts.expectedOnly) {298        for (let i = 0; i < addedKeys.length; i++) {299          const key = addedKeys[i]300          const val = act[key]301          const addDiff = diff(val, val, path.concat([key]))302          _.defaults(opts, addDiff.opts)303          act[key] = addDiff.act304          if (act[key] === undefined) continue305          if (opts.failedMatcher) {306            subOutput += addDiff.text307          } else {308            subOutput += fmt.keyAdded(key, act[key])309          }310          changed = true311        }312      }313      if (changed) {314        text = fmt.wrapObjectLike(exp, act, subOutput)315      }316    } else if (match.isMatcher(exp)) {317      debug('is matcher')318      if (!testValue(exp, act)) {319        text = fmt.wrap('failed', `${chalk.green(printVar(act))} ⛔  ${matcherStringToObj(exp.message).toJSON()}`)320        changed = true321      }322    } else if (isObject(act)) {323      debug('only act is obj')324      const addDiff = diff({}, act, path, { expectedOnly: false })325      _.defaults(opts, addDiff.opts)326      return _.extend({},327        addDiff, {328          changed: true,329          text: fmt.wrap('removed', `${printVar(exp)}\n${fmt.wrap('added', addDiff.text)}`),330        })331    } else {332      debug('neither is obj')333      exp = printVar(exp)334      act = printVar(act)335      if (exp !== act) {336        text = fmt.wrap('modified', `${exp} ${typeColors['normal']('⮕')} ${act}`)337        changed = true338      }339    }340    return {341      changed,342      text,343      act,344      opts,345    }346  }347  return diff348}349module.exports = {350  registerInCypress,351  matchDeep,352  stringifyShort,353  parseMatcherFromString,...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My First Test', function() {2  it('Does not do much!', function() {3    cy.contains('type').click()4    cy.url().should('include', '/commands/actions')5    cy.get('.action-email')6      .type('

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My First Test', function() {2  it('Does not do much!', function() {3    cy.contains('type').click()4    cy.url().should('include', '/commands/actions')5    cy.get('#email1')6      .type('

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My First Test', function() {2    it('Does not do much!', function() {3        cy.contains('type').click()4        cy.url().should('include', '/commands/actions')5        cy.get('.action-email')6            .type('

Full Screen

Using AI Code Generation

copy

Full Screen

1import { matchDeepCypress } from "match-deep-cypress";2import { matchDeepChai } from "match-deep-cypress";3describe("matchDeepCypress", () => {4  it("should match the object", () => {5    const actual = {6      address: {7      }8    };9    const expected = {10      address: {11      }12    };13    matchDeepCypress(actual, expected);14  });15});16describe("matchDeepChai", () => {17  it("should match the object", () => {18    const actual = {19      address: {20      }21    };22    const expected = {23      address: {24      }25    };26    matchDeepChai(actual, expected);27  });28});29import { matchDeepCypress } from "match-deep-cypress";30Cypress.Commands.add("matchDeepCypress", matchDeepCypress);31import { matchDeepChai } from "match-deep-cypress";32chai.use(matchDeepChai);33describe("matchDeepCypress", () => {34  it("should match the object", () => {35    const actual = {36      address: {37      }38    };39    const expected = {40      address: {41      }42    };43    cy.matchDeepCypress(actual, expected);44  });45});46describe("matchDeepChai", () => {47  it("should match the object", () => {

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('Test', function() {2    it('Test', function() {3        cy.get('input[name="q"]').type('Cypress')4        cy.get('input[name="btnK"]').click()5        cy.get('div#rso > div > div > div > div > div > div > a > h3').matchDeepCypress('Cypress')6    })7})8Cypress.Commands.add('matchDeepCypress', { prevSubject: true }, (subject, textToMatch) => {9    cy.wrap(subject).should('contain', textToMatch)10})11module.exports = (on, config) => {12    on('task', {13        matchDeepCypress(subject, textToMatch) {14            if (subject.includes(textToMatch)) {15            } else {16            }17        }18    })19}20Cypress.Commands.add('matchDeepCypress', { prevSubject: true }, (subject, textToMatch) => {21    cy.wrap(subject).should('contain', textToMatch)22})23module.exports = (on, config) => {24    on('task', {25        matchDeepCypress(subject, textToMatch) {26            if (subject.includes(textToMatch)) {

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('example', () => {2  it('should match', () => {3    cy.wrap({ a: 1, b: 2 }).matchDeepCypress({ a: 1 });4  });5});6declare namespace Cypress {7  interface Chainable {8    matchDeepCypress: typeof matchDeepCypress;9  }10}11const matchDeepCypress = (expected) => {12  cy.wrap(this).should('deep.equal', expected);13};14Cypress.Commands.add('matchDeepCypress', matchDeepCypress);15declare namespace Cypress {16  interface Chainable {17    matchDeepCypress: typeof matchDeepCypress;18  }19}20const matchDeepCypress = (expected) => {21  cy.wrap(this).should('deep.equal', expected);22};23Cypress.Commands.add('matchDeepCypress', matchDeepCypress);24declare namespace Cypress {25  interface Chainable {26    matchDeepCypress: typeof matchDeepCypress;27  }28}29const matchDeepCypress = (expected) => {30  cy.wrap(this).should('deep.equal', expected);31};32Cypress.Commands.add('matchDeepCypress', matchDeepCypress);33declare namespace Cypress {34  interface Chainable {35    matchDeepCypress: typeof matchDeepCypress;36  }37}38const matchDeepCypress = (expected) => {39  cy.wrap(this).should('deep.equal', expected);40};41Cypress.Commands.add('matchDeepCypress', matchDeepCypress);42declare namespace Cypress {43  interface Chainable {44    matchDeepCypress: typeof matchDeepCypress;45  }46}47const matchDeepCypress = (expected

Full Screen

Using AI Code Generation

copy

Full Screen

1import 'cypress-match-deep';2import 'cypress-match-deep/chai';3describe('test matchDeep', () => {4  it('test matchDeepCypress', () => {5    const obj1 = {6      address: {7      },8    };9    const obj2 = {10      address: {11      },12    };13    cy.wrap(obj1).matchDeepCypress(obj2);14  });15  it('test matchDeepChai', () => {16    const obj1 = {17      address: {18      },19    };20    const obj2 = {21      address: {22      },23    };24    expect(obj1).matchDeepChai(obj2);25  });26});

Full Screen

Cypress Tutorial

Cypress is a renowned Javascript-based open-source, easy-to-use end-to-end testing framework primarily used for testing web applications. Cypress is a relatively new player in the automation testing space and has been gaining much traction lately, as evidenced by the number of Forks (2.7K) and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.

Chapters:

  1. What is Cypress? -
  2. Why Cypress? - Learn why Cypress might be a good choice for testing your web applications.
  3. Features of Cypress Testing - Learn about features that make Cypress a powerful and flexible tool for testing web applications.
  4. Cypress Drawbacks - Although Cypress has many strengths, it has a few limitations that you should be aware of.
  5. Cypress Architecture - Learn more about Cypress architecture and how it is designed to be run directly in the browser, i.e., it does not have any additional servers.
  6. Browsers Supported by Cypress - Cypress is built on top of the Electron browser, supporting all modern web browsers. Learn browsers that support Cypress.
  7. Selenium vs Cypress: A Detailed Comparison - Compare and explore some key differences in terms of their design and features.
  8. Cypress Learning: Best Practices - Take a deep dive into some of the best practices you should use to avoid anti-patterns in your automation tests.
  9. How To Run Cypress Tests on LambdaTest? - Set up a LambdaTest account, and now you are all set to learn how to run Cypress tests.

Certification

You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.

YouTube

Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.

Run Cypress automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful