Skip to content

Commit

Permalink
working more on cypress support
Browse files Browse the repository at this point in the history
  • Loading branch information
bahmutov committed Feb 3, 2017
1 parent 5b45b28 commit e90df4b
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 20 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ node_modules/
npm-debug.log
src/.snap-shot/
.snap-shot
snap-shot.json
9 changes: 5 additions & 4 deletions cypress/integration/spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ const snapshot = require('../..')
describe('snap-shot', () => {
const url = __dirname + '/index.html'

beforeEach(snapshot.init)
before(snapshot.init)

it('works without snapshot', () => {
expect(cy).to.be.an('object')
})

it('works', () => {
it.only('works', () => {
cy.log('calling snap shot')
snapshot('foo')
})

Expand All @@ -17,9 +18,9 @@ describe('snap-shot', () => {
.title().should('equal', 'snap-shot')

// same with snap-shot multiple lines
cy.title().then(title =>
cy.title().then(title => {
snapshot(title)
)
})
})

it('works with arrow function', () => {
Expand Down
96 changes: 96 additions & 0 deletions src/cypress-system.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
'use strict'

const la = require('lazy-ass')
const is = require('check-more-types')
const callsites = require('callsites')

// storage adapter for Cypress E2E testing tool

/* global cy, expect, fetch */
const filename = 'snap-shot.json'

let snapshots

function loadSnapshots () {
return snapshots
}

function saveSnapshots (snapshots) {
const text = JSON.stringify(snapshots, null, 2) + '\n'
cy.writeFile(filename, text)
}

function init () {
// find out the source for all test -> this spec file
const sites = callsites()
la(sites.length, 'missing callsite')
const specFileUrl = sites[0].getFileName()
la(is.webUrl(specFileUrl), 'missing spec url', specFileUrl)
console.log('loading spec from', specFileUrl)

// specFileUrl is something like
// http://localhost:49829/__cypress/tests?p=cypress/integration/spec.js-438
// we will need to get "true" filename which in this case should be
// cypress/integration/spec.js
const pIndex = specFileUrl.indexOf('?p=')
const dotJsIndex = specFileUrl.indexOf('.js-', pIndex)
const specFile = specFileUrl.substr(pIndex + 3, dotJsIndex - pIndex)
console.log('specFile is "%s"', specFile)

// ignore arguments for now
api.fromCurrentFolder = () => specFile

// cache the fetched source, otherwise every test fetches it
const shouldFetch = api.readFileSync === dummyReadFileSync
if (shouldFetch) {
return fetch(specFileUrl).then(r => r.text())
.then(source => {
// ignores filename for now
api.readFileSync = () => source
})
.then(() => {
return fetch('/__cypress/tests?p=' + filename)
.then(r => r.text())
.then(text => {
if (text.includes('BUNDLE_ERROR')) {
return Promise.reject(new Error('not found'))
}
cy.log('loaded snapshots', filename)
// the JSON is wrapped in webpack wrapper ;)
const req = eval(text) // eslint-disable-line no-eval
snapshots = req('1')
})
.catch(err => {
console.error(err)
snapshots = {}
})
})
} else {
return Promise.resolve()
}
}

function raiseIfDifferent ({value, expected}) {
cy.then(() => {
expect(value).to.equal(expected)
})
}

function dummyReadFileSync () {
throw new Error(`In the browser, please call snapshot.init()
before calling tests, like this:
const snapshot = require('snap-shot')
beforeEach(snapshot.init)
`)
}

// TODO replace exposed API with error methods that wait
// until "init" is called
const api = {
loadSnapshots,
saveSnapshots,
init,
readFileSync: dummyReadFileSync,
raiseIfDifferent
}
module.exports = api
16 changes: 15 additions & 1 deletion src/file-system.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

const fs = require('fs')
const path = require('path')
const diff = require('variable-diff')
const debug = require('debug')('snap-shot')

const cwd = process.cwd()
const fromCurrentFolder = path.relative.bind(null, cwd)
Expand Down Expand Up @@ -33,9 +35,21 @@ function saveSnapshots (snapshots) {
return snapshots
}

function raiseIfDifferent ({value, expected, specName}) {
const diffed = diff(expected, value)
if (diffed.changed) {
const text = diffed.text
debug('Test "%s" snapshot difference', specName)
const msg = `snapshot difference\n${text}`
console.log(msg)
throw new Error(msg)
}
}

module.exports = {
readFileSync: fs.readFileSync,
fromCurrentFolder,
loadSnapshots,
saveSnapshots
saveSnapshots,
raiseIfDifferent
}
46 changes: 31 additions & 15 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,25 @@ const callsites = require('callsites')
const falafel = require('falafel')
const la = require('lazy-ass')
const is = require('check-more-types')
const diff = require('variable-diff')
const crypto = require('crypto')
const {snapshotIndex} = require('./utils')

// does this test work with jsdom?
const isBrowser = typeof window === 'object' &&
(typeof global === 'undefined' || window === global)
const isCypress = typeof cy === 'object'
const isNode = !isBrowser
const fs = isNode ? require('./file-system') : require('./browser-system')
let fs
if (isNode) {
fs = require('./file-system')
} else if (isCypress) {
fs = require('./cypress-system')
} else {
fs = require('./browser-system')
}

const shouldUpdate = Boolean(process.env.UPDATE)

const snapshots = fs.loadSnapshots()

function isTestFunctionName (name) {
return ['it', 'test'].includes(name)
}
Expand Down Expand Up @@ -100,6 +105,18 @@ function getSpecFunction ({file, line}) {
}
}

const cacheResult = fn => {
let result
return () => {
if (!result) {
result = fn()
}
return result
}
}

const loadSnapshots = cacheResult(fs.loadSnapshots)

function findStoredValue ({file, specName, index = 0}) {
const relativePath = fs.fromCurrentFolder(file)
// console.log('relativePath', relativePath)
Expand All @@ -109,6 +126,7 @@ function findStoredValue ({file, specName, index = 0}) {
return
}

const snapshots = loadSnapshots()
if (!snapshots[relativePath]) {
return
}
Expand All @@ -129,6 +147,7 @@ function storeValue ({file, specName, index, value}) {
la(is.number(index), 'missing snapshot index', file, specName, index)

const relativePath = fs.fromCurrentFolder(file)
const snapshots = fs.loadSnapshots()
// console.log('relativePath', relativePath)
if (!snapshots[relativePath]) {
snapshots[relativePath] = {}
Expand Down Expand Up @@ -198,19 +217,16 @@ function snapshot (what, update) {
debug('spec "%s" snapshot at line %d is #%d',
specName, snapshotRelativeLine, index)

const storedValue = findStoredValue({file, specName, index})
if (update || storedValue === undefined) {
const expected = findStoredValue({file, specName, index})
if (update || expected === undefined) {
storeValue({file, specName, index, value})
} else {
debug('found snapshot for "%s", value', specName, storedValue)
const diffed = diff(storedValue, value)
if (diffed.changed) {
const text = diffed.text
debug('Test "%s" snapshot difference', specName)
const msg = `snapshot difference\n${text}`
console.log(msg)
throw new Error(msg)
}
debug('found snapshot for "%s", value', specName, expected)
fs.raiseIfDifferent({
value,
expected,
specName
})
}

return value
Expand Down

0 comments on commit e90df4b

Please sign in to comment.