| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- 'use strict'
- const assertionCommands = [
- // assertions
- 'should',
- 'and',
- 'contains',
- // retries until it gets something
- 'get',
- // not an assertion, but unlikely to require waiting for render
- 'scrollIntoView',
- 'scrollTo',
- ]
- module.exports = {
- meta: {
- docs: {
- description: 'Assert on the page state before taking a screenshot, so the screenshot is consistent',
- category: 'Possible Errors',
- recommended: false,
- },
- schema: [],
- messages: {
- unexpected: 'Make an assertion on the page state before taking a screenshot',
- },
- },
- create (context) {
- return {
- CallExpression (node) {
- if (isCallingCyScreenshot(node) && !isPreviousAnAssertion(node)) {
- context.report({ node, messageId: 'unexpected' })
- }
- },
- }
- },
- }
- function isRootCypress (node) {
- while (node.type === 'CallExpression') {
- if (node.callee.type !== 'MemberExpression') return false
- if (node.callee.object.type === 'Identifier' &&
- node.callee.object.name === 'cy') {
- return true
- }
- node = node.callee.object
- }
- return false
- }
- function getPreviousInChain (node) {
- return node.type === 'CallExpression' &&
- node.callee.type === 'MemberExpression' &&
- node.callee.object.type === 'CallExpression' &&
- node.callee.object.callee.type === 'MemberExpression' &&
- node.callee.object.callee.property.type === 'Identifier' &&
- node.callee.object.callee.property.name
- }
- function getCallExpressionCypressCommand (node) {
- return isRootCypress(node) &&
- node.callee.property.type === 'Identifier' &&
- node.callee.property.name
- }
- function isCallingCyScreenshot (node) {
- return getCallExpressionCypressCommand(node) === 'screenshot'
- }
- function getPreviousCypressCommand (node) {
- const previousInChain = getPreviousInChain(node)
- if (previousInChain) {
- return previousInChain
- }
- while (node.parent && !node.parent.body) {
- node = node.parent
- }
- if (!node.parent || !node.parent.body) return null
- const body = node.parent.body.type === 'BlockStatement' ? node.parent.body.body : node.parent.body
- const index = body.indexOf(node)
- // in the case of a function declaration it won't be found
- if (index < 0) return null
- if (index === 0) return getPreviousCypressCommand(node.parent)
- const previousStatement = body[index - 1]
- if (previousStatement.type !== 'ExpressionStatement' ||
- previousStatement.expression.type !== 'CallExpression') {
- return null
- }
- return getCallExpressionCypressCommand(previousStatement.expression)
- }
- function isPreviousAnAssertion (node) {
- const previousCypressCommand = getPreviousCypressCommand(node)
- return assertionCommands.indexOf(previousCypressCommand) >= 0
- }
|