Skip to content

Commit

Permalink
Fix formatting in Command Log test results. (#5619)
Browse files Browse the repository at this point in the history
* Preserve number strings.

* Fixed warning caused by exception.

* Fixed excessive quotation marks. And added related tests to show this.

* Show keys properly.

* Minor fixes: arrowify, use backtick.

* Added tests.

* Fixed confusing asterisks.
  • Loading branch information
sainthkh authored and kuceb committed Nov 12, 2019
1 parent 46ad71a commit d65ee30
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 12 deletions.
42 changes: 30 additions & 12 deletions packages/driver/src/cy/chai.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@ const $dom = require('../dom')
const $utils = require('../cypress/utils')
const $chaiJquery = require('../cypress/chai_jquery')

// all words between single quotes which are at
// the end of the string
const allPropertyWordsBetweenSingleQuotes = /('.*?')$/g

// grab all words between single quotes except
// when the single quote word is the LAST word
const allButLastWordsBetweenSingleQuotes = /('.*?')(.+)/g
// all words between single quotes
const allPropertyWordsBetweenSingleQuotes = /('.*?')/g

const allBetweenFourStars = /\*\*.*\*\*/
const allNumberStrings = /'([0-9]+)'/g
const allEmptyStrings = /''/g
const allSingleQuotes = /'/g
const allEscapedSingleQuotes = /\\'/g
const allQuoteMarkers = /__quote__/g
const allWordsBetweenCurlyBraces = /(#{.+?})/g
const allQuadStars = /\*\*\*\*/g
const leadingWhitespaces = /\*\*'\s*/g
const trailingWhitespaces = /\s*'\*\*/g
const whitespace = /\s/g
const valueHasLeadingOrTrailingWhitespaces = /\*\*'\s+|\s+'\*\*/g

let assertProto = null
let matchProto = null
Expand Down Expand Up @@ -78,26 +79,43 @@ chai.use((chai, u) => {
existProto = Object.getOwnPropertyDescriptor(chai.Assertion.prototype, 'exist').get;
({ getMessage } = chaiUtils)

// remove any single quotes between our **, preserving escaped quotes
// and if an empty string, put the quotes back
// remove any single quotes between our **,
// except escaped quotes, empty strings and number strings.
const removeOrKeepSingleQuotesBetweenStars = (message) => {
return message.replace(allBetweenFourStars, (match) => {
if (valueHasLeadingOrTrailingWhitespaces.test(match)) {
// Above we used \s+, but below we use \s*.
// It's because of the strings like ' love' that have empty spaces on one side only.
match = match
.replace(leadingWhitespaces, (match) => {
return match.replace(`**'`, '**__quote__')
.replace(whitespace, ' ')
})
.replace(trailingWhitespaces, (match) => {
return match.replace(`'**`, '__quote__**')
.replace(whitespace, ' ')
})
}

return match
.replace(allEscapedSingleQuotes, '__quote__') // preserve escaped quotes
.replace(allNumberStrings, '__quote__$1__quote__') // preserve number strings (e.g. '42')
.replace(allEmptyStrings, '__quote____quote__') // preserve empty strings (e.g. '')
.replace(allSingleQuotes, '')
.replace(allQuoteMarkers, '\'') // put escaped quotes back
.replace(allQuadStars, '**\'\'**')
})
} // fix empty strings that end up as ****
}

const replaceArgMessages = (args, str) => {
return _.reduce(args, (memo, value, index) => {
if (_.isString(value)) {
value = value
.replace(allWordsBetweenCurlyBraces, '**$1**')
.replace(allEscapedSingleQuotes, '__quote__')
.replace(allButLastWordsBetweenSingleQuotes, '**$1**$2')
.replace(allPropertyWordsBetweenSingleQuotes, '**$1**')
// when a value has ** in it, **** are sometimes created after the process above.
// remove them with this.
.replace(allQuadStars, '**')

memo.push(value)
} else {
Expand Down
104 changes: 104 additions & 0 deletions packages/driver/test/cypress/integration/commands/assertions_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,110 @@ describe('src/cy/commands/assertions', () => {
})
})

context('format quotation marks', () => {
const expectMarkdown = (test, message, done) => {
cy.then(() => {
test()
})

cy.on('log:added', (attrs, log) => {
if (attrs.name === 'assert') {
cy.removeAllListeners('log:added')

expect(log.get('message')).to.eq(message)

done()
}
})
}

it('preserves quotation marks in number strings', (done) => {
expectMarkdown(() => {
try {
expect(25).to.eq('25')
} catch (error) {} /* eslint-disable-line no-empty */
},
`expected **25** to equal **'25'**`,
done)
})

it('preserves quotation marks in empty string', (done) => {
expectMarkdown(() => {
try {
expect(42).to.eq('')
} catch (error) {} /* eslint-disable-line no-empty */
},
`expected **42** to equal **''**`,
done)
})

it('preserves quotation marks if escaped', (done) => {
expectMarkdown(
() => expect(`\'cypress\'`).to.eq(`\'cypress\'`),
// ****'cypress'**** -> ** for emphasizing result string + ** for emphasizing the entire result.
`expected **'cypress'** to equal ****'cypress'****`,
done
)
})

it('removes quotation marks in DOM elements', (done) => {
expectMarkdown(
() => {
cy.get('body').then(($body) => {
expect($body).to.contain('div')
})
},
`expected **<body>** to contain **div**`,
done
)
})

it('removes quotation marks in strings', (done) => {
expectMarkdown(() => expect('cypress').to.eq('cypress'), `expected **cypress** to equal **cypress**`, done)
})

it('removes quotation marks in objects', (done) => {
expectMarkdown(
() => expect({ foo: 'bar' }).to.deep.eq({ foo: 'bar' }),
`expected **{ foo: bar }** to deeply equal **{ foo: bar }**`,
done
)
})

it('formats keys properly for "have.all.keys"', (done) => {
const person = {
name: 'Joe',
age: 20,
}

expectMarkdown(
() => expect(person).to.have.all.keys('name', 'age'),
`expected **{ name: Joe, age: 20 }** to have keys **name**, and **age**`,
done
)
})

describe('formats strings with spaces', (done) => {
const tester = (message, done) => {
const nbspedMsg = message
.replace(/^\s+/, (match) => {
return match.replace(/\s/g, '&nbsp;')
})
.replace(/\s+$/, (match) => {
return match.replace(/\s/g, '&nbsp;')
})

expectMarkdown(() => expect(message).to.eq(message), `expected **'${nbspedMsg}'** to equal **'${nbspedMsg}'**`, done)
}

[' 37:46 ', ' test ', ' love'].forEach((v) => {
it(v, (done) => {
tester(v, done)
})
})
})
})

context('chai overrides', () => {
beforeEach(function () {
this.$body = cy.$$('body')
Expand Down

4 comments on commit d65ee30

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on d65ee30 Nov 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

You can install this pre-release platform-specific build using instructions at https://on.cypress.io/installing-cypress#Install-pre-release-version.

You will need to use custom CYPRESS_INSTALL_BINARY url and install Cypress using an url instead of the version.

export CYPRESS_INSTALL_BINARY=https://cdn.cypress.io/beta/binary/3.6.2/linux-x64/circle-develop-d65ee3045e1ad08acfa3159fa75bcfb811f77738-189243/cypress.zip
npm install https://cdn.cypress.io/beta/npm/3.6.2/circle-develop-d65ee3045e1ad08acfa3159fa75bcfb811f77738-189235/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on d65ee30 Nov 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppVeyor has built the win32 ia32 version of the Test Runner.

You can install this pre-release platform-specific build using instructions at https://on.cypress.io/installing-cypress#Install-pre-release-version.

You will need to use custom CYPRESS_INSTALL_BINARY url and install Cypress using an url instead of the version.

set CYPRESS_INSTALL_BINARY=https://cdn.cypress.io/beta/binary/3.6.2/win32-ia32/appveyor-develop-d65ee3045e1ad08acfa3159fa75bcfb811f77738-28803098/cypress.zip
npm install https://cdn.cypress.io/beta/binary/3.6.2/win32-ia32/appveyor-develop-d65ee3045e1ad08acfa3159fa75bcfb811f77738-28803098/cypress.zip

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on d65ee30 Nov 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppVeyor has built the win32 x64 version of the Test Runner.

You can install this pre-release platform-specific build using instructions at https://on.cypress.io/installing-cypress#Install-pre-release-version.

You will need to use custom CYPRESS_INSTALL_BINARY url and install Cypress using an url instead of the version.

set CYPRESS_INSTALL_BINARY=https://cdn.cypress.io/beta/binary/3.6.2/win32-x64/appveyor-develop-d65ee3045e1ad08acfa3159fa75bcfb811f77738-28803098/cypress.zip
npm install https://cdn.cypress.io/beta/binary/3.6.2/win32-x64/appveyor-develop-d65ee3045e1ad08acfa3159fa75bcfb811f77738-28803098/cypress.zip

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on d65ee30 Nov 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

You can install this pre-release platform-specific build using instructions at https://on.cypress.io/installing-cypress#Install-pre-release-version.

You will need to use custom CYPRESS_INSTALL_BINARY url and install Cypress using an url instead of the version.

export CYPRESS_INSTALL_BINARY=https://cdn.cypress.io/beta/binary/3.6.2/darwin-x64/circle-develop-d65ee3045e1ad08acfa3159fa75bcfb811f77738-189249/cypress.zip
npm install https://cdn.cypress.io/beta/npm/3.6.2/circle-develop-d65ee3045e1ad08acfa3159fa75bcfb811f77738-189247/cypress.tgz

Please sign in to comment.