libreoffice-online/cypress_test/eslint_plugin/index.js
Tamás Zolnai 8853547ee0 cypress: add no-get-invoke-match-chain rule.
We can avoid retriability problems caused by using
this long chain as an indicator in tests.

Change-Id: Iec78087d080c3759e446a061222eb4d9f4dd3ae5
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/95280
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Tested-by: Jenkins
Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com>
2020-06-01 14:09:53 +02:00

60 lines
2.6 KiB
JavaScript

module.exports = {
rules: {
'no-get-contains-chain': {
/**
* Catches cy.get(selector).contains(content) calls in the code.
*
* Issue: In cypress test framework only the last command is retried.
* In this case it's the contains method and so the get() method is
* not retried. Sometimes, it behaves unexpectedly, because the DOM
* has the correct item matching with both the selector and the content,
* but the test still fails on this command chain.
*
* Fix 1: When we use the content as a selector. In this case, we can use
* cy.contains(selector, content) instead. This is compact command which
* will retry to match both the selector and the content.
*
* Fix 2: When we need an assertion about the content. In this case, we can
* use cy.contains(selector, content) or cy.get(selector).should('have.text', content)
* is also a good replacement.
*
**/
create: function(context) {
return {
'CallExpression[callee.property.name=\'contains\'][callee.object.callee.property.name=\'get\']': function(node) {
context.report(node, 'Do not chain get() and contains(). Use cy.contains(selector, content) instead for better retriability!');
}
};
}
},
'no-get-invoke-match-chain': {
/**
* Catches cy.get(selector).invoke('text').should('match',...) calls in the code.
*
* Issue: In cypress test framework only the last getter command is retried.
* In this case it's the invoke method and so the get() method is
* not retried. Sometimes, it behaves unexpectedly, because the test
* retries to call the text method on an element, which might be removed
* in the meantime. Instead of searching for a new element matching both
* with the selector and the regular expression.
*
* Fix: We can use cy.contains(seletor, regexp) method instead.
* This is a compact command which will retry to match both the
* selector and the text matcher.
*
**/
create: function(context) {
return {
'CallExpression[callee.property.name=\'should\'][callee.object.callee.property.name=\'invoke\'][callee.object.callee.object.callee.property.name=\'get\']': function(expr) {
if (expr.arguments && expr.arguments.length === 2 && expr.arguments[0].value === 'match' &&
expr.callee.object.arguments &&
expr.callee.object.arguments.length === 1 &&
expr.callee.object.arguments[0].value === 'text') {
context.report(expr, 'Do not use this long chain for matching text. Use cy.contains(selector, regexp) instead for better retriability!');
}
}
};
}
}
}
};