Releases: automician/cypress-selene
Releases · automician/cypress-selene
v1.0.0-alpha.2
locator.first(), locator.last()
Added
- locator.first(), locator.last()
1.0.0-alpha.1
Initial version with Lazy elements, full retryability and extra conditions with aliases
Added
-
Locator class as Lazy and Fluent API wrapper
- over
cy.get(selector)
,.filter(selector)
- with
.by(selector)
alias,
with additional selector conversions
see custom commands explanations below;)
- with
.not(selector)
with additional selector conversions
see custom commands explanations below;).find(selector)
.eq(index)
.next(selector)
.should(matcher, *args)
- with all methods above
- being lazy, returning same Locator instance with "updated" selector path
- so you can store it in the var, like
const active = new Locator({path: '#todo-list>li'}).not('.completed')
- so you can store it in the var, like
- being fully retriable (cypress only retries the last command)
- with integrated smart waits/assertions per retry
so you see in log what was the reason of retry and its failure in the worst case
i.e. you can break down long selectors into parts in order to see in the log the exact problematic part
and so fasten your tests support ;)
- with integrated smart waits/assertions per retry
- being lazy, returning same Locator instance with "updated" selector path
- with non lazy commands, that actually find subject to perform actual actions
locator.get()
returning actual cy subject- here the lazyness ends, and all subsequent API is a raw Cypress one,
i.e. not lazy, and you can not store it into vars) - it's usefull to force it to get raw subject and use classic cy command that is not yet available in Locator.*
- here the lazyness ends, and all subsequent API is a raw Cypress one,
locator.type(text)
locator.clear()
locator.submit()
locator.setValue(text)
- as alias to
.clear().type(text)
- as alias to
locator.click()
locator.doubleClick()
- as more user-oriented alias to
.dbclick
- as more user-oriented alias to
locator.hover()
- as alias to .trigger('mousover')
locator.pressEnter()
locator.pressEscape()
- over
-
globals
- ... planned to be removed from globals in newer versions ;)
- Selene's style
browser
as alias tocy
- for more user-oriented
browser.visit('https://url.org')
overcy.visit('https://url.org')
- for more user-oriented
s(selector)
as alias to newLocator({path: selector})
- to allow lazy (also with full retriability)
over not-fully-retriable and lazy-only-via-functions
const todos = s('#todo-list>li) //... todos.should(/*...*/) todos.filter('.completed').should(/*...*/)
const todos = () => cy.get('#todo-list>li) //... todos().should(/*...*/) todos().filter('.completed').should(/*...*/) // Cypress retries only .filter(...) here
- to allow lazy (also with full retriability)
be.*
andhave.*
- as aliases to some most used cypress «chainers/matchers/conditions»
- for cleaner code (when reviewing it will be easier to distinguish code from test data;):
over
s('#todo-list>li').eq(1).should(have.text, 'i am test data, emphasized by quotes;)')
s('#todo-list>li').eq(2).should('have.text', 'of same style as prev arg')
-
customized commands
- new
cy.the(wordOrSmarterSelector)
in addition tocy.get(selector)
- to consider all words as values of
data-qa
attributes
i.e.cy.the('submit')
is same ascy.get('[data-qa=submit]')
support of customizing such «data qa attributes» will be added later #2 - to support Playwright style «search by text»
i.e.cy.the('text=Press me')
is same ascy.contains('Press me')
- same as
cy.get(selector)
otherwise - support of customizing such conversions will be added later #3
- to consider all words as values of
cy.by(smarterSelector)
as alias tocy.filter(selector)
- for conciseness
- and smarter conversions:
P.S.
cy.get('.todo').by(':contains("Write a test!")') cy.get('.todo').by('text=Write a test') // same as above cy.get('.todo').by('.completed') // same as cy.get('.todo').filter('.completed') cy.get('.todo').by(':not(.completed)') // same as cy.get('.todo').not('.completed') cy.get('.todo').by(':has(img.high-priority-flag)') // same as cy.get('.todo').filter(':has(img.high-priority-flag)') cy.get('.todo').by(' img.high-priority-flag') // same as above cy.get('.todo').by(':has(>img.high-priority-flag)') cy.get('.todo').by('>img.high-priority-flag') // same as above
s(selector)
is also available
for even conciser:s('.todo').by('text=Write a test') s('.todo').by('.completed')
- overwritten
cy.not
for same conversions as in customcy.by
- new
-
customized conditions (matchers)
- new
have.texts(...partialValues)
- for conciser version
over raw cypress
s('#todo-list li').should(have.texts, 'a', 'c')
... 🤦🏻♂️ – check real official examplecy.get('@todo-list li').as('todos') //... cy.get('@todos').should('have.length', 2) cy.get('@todos') .eq(0) .should('contain', 'a') cy.get('@todos') .eq(1) .should('contain', 'c')
- for conciser version
have.exactTexts(...values)
have.elements(selector)
orhave.the(selector)
- as alias to
.should(($elements) => { expect($elements.has(selector).length).to.be.gt(0) })
- as alias to
have.filtered(selector)
- as alias to
.should(($elements) => { expect($elements.filter(selector).length).to.be.gt(0) })
- as alias to
- changed in alias (have.* or be.*)
- for better readability according to native english in
be.*
stylebe.equalTo
over'equal'
be.matching
over'match'
be.containing
over'contain'
have.valueContaining
over'contain.value'
be.inDOM
over'exist'
for less confusion in understanding from the user perspectivehave.text
over'include.text'
as in Selenide/Selene,
because in native english «have text» naturally means «have some text inside»have.exactText
over'have.text'
as in Selenide/Selene,have.cssClass
over'have.class'
as in Selenide/Selene
for less confusion, because «class» is also the whole attribute
that can contain many «css classes»
- for better readability according to native english in
- new