Extra Cypress query commands for v12+
Add this package as a dev dependency:
$ npm i -D cypress-map
# or using Yarn
$ yarn add -D cypress-map
Include this package in your spec or support file to use all custom query commands
import 'cypress-map'
Alternative: import only the query commands you need:
import 'cypress-map/commands/map'
import 'cypress-map/commands/tap'
// and so on, see the /commands folder
const double = (n) => n * 2
cy.wrap(100).apply(double).should('equal', 200)
It works like cy.then but cy.apply(fn) is a query command. Function fn should be synchronous, pure function that only uses the subject argument and returns new value The function callback fn cannot use any Cypress commands cy.
You can pass additional left arguments to the callback function. Then it puts the subject as last argument before calling the function:
cy.wrap(8).apply(Cypress._.subtract, 4).should('equal', -4)
Yields the subject of the same type as the fn return.
Without arguments, cy.applyRight works the same as cy.apply. If you pass arguments, then the subject plus the arguments become the arguments to the callback. The subject is at the left (first) position
cy.wrap(8).applyRight(Cypress._.subtract, 4).should('equal', 4)
// same as
cy.wrap(8)
.apply((subject) => Cypress._.subtract(subject, 4))
.should('equal', 4)
Sometimes you have the callback to apply, and you know the first argument(s), and just need to put the subject at the last position. This is where you can partially apply the known arguments to the given callback.
// the Cypress._.add takes to arguments (a, b)
// we know the first argument a = 5
// so we partially apply it and wait for the subject = b argument
cy.wrap(100).partial(Cypress._.add, 5).should('equal', 105)
// same as
cy.wrap(100)
.apply((subject) => Cypress._.add(5, subject))
.should('equal', 105)
If the current subject is an array, or a jQuery object, you can apply the given callback with arguments to the first item or element. The current subject will be the last argument.
// cy.applyToFirst(callback, ...args)
cy.wrap(Cypress.$('
100
200
'))
.applyToFirst((base, el) => parseInt(el.innerText, base), 10)
.should('equal', 100)
If the current subject is an array, or a jQuery object, you can apply the given callback with arguments to the first item or element. The current subject will be the first argument.
// cy.applyToFirstRight(callback, ...args)
cy.wrap(Cypress.$('
100
200
'))
.applyToFirstRight((el, base) => parseInt(el.innerText, base), 10)
.should('equal', 100)
We often just need to call a method on the first element / item in the current subject
cy.get(selector).invokeFirst('getBoundingClientRect')
// compute the vertical center for example
Transforms every object in the given collection by running it through the given callback function. Can also map each object to its property. An object could be an array or a jQuery object.
// map elements by invoking a function
cy.wrap(['10', '20', '30']).map(Number) // [10, 20, 30]
// map elements by a property
cy.get('.matching')
.map('innerText')
.should('deep.equal', ['first', 'third', 'fourth'])
You can even map properties of an object by listing callbacks. For example, let's convert the age property from a string to a number for a single object:
cy.wrap({
age: '42',
lucky: true,
})
.map({
age: Number,
})
.should('deep.equal', {
age: 42,
lucky: true,
})
If the subject is an array, then mapping will go through each item
const people = [...]
// each item in the "people" array
// has "age" property that we want to convert from a string
// to a number
cy.wrap(people)
.map({
age: parseInt
})
You can avoid any conversion to simply pick the list of properties from an object
const person = {
name: 'Joe',
age: 21,
occupation: 'student',
}
cy.wrap(person).map(['name', 'age']).should('deep.equal', {
name: 'Joe',
age: 21,
})
You can extract nested paths by using "." in your property path
cy.wrap(people)
.map('name.first')
.should('deep.equal', ['Joe', 'Anna'])
// equivalent to
cy.wrap(people)
.map('name')
.map('first')
.should('deep.equal', ['Joe', 'Anna'])
If you want to pick multiple deep properties, the last segment will be the output property name
// each person has nested objects like
// { name: { first: '...', last: '...', }, human: { age: xx, ... } }
cy.wrap(people).map(['name.first', 'human.age'])
// each object will have "first" and "age" properties
If the subject is an array of arrays, you can get each element by index
cy.wrap([
[1, 2, 3],
[4, 5, 6],
])
.map(1)
.should('deep.equal', [2, 5])
cy.get('#items li')
.find('.price')
.map('innerText')
.mapInvoke('replace', '$', '')
.mapInvoke('trim')
cy.get('#items li')
.find('.price')
.map('innerText')
.mapInvoke('replace', '$', '')
.map(parseFloat)
.reduce((max, n) => (n > max ? n : max))
// yields the highest price
You can provide the initial accumulator value
cy.wrap([1, 2, 3])
.reduce((sum, n) => sum + n, 10)
.should('equal', 16)
See reduce.cy.js
cy.get('#items li')
.find('.price')
.map('innerText')
.tap() // console.log by default
.mapInvoke('replace', '$', '')
.mapInvoke('trim')
// console.info with extra label
.tap(console.info, 'trimmed strings')
Notice: if the label is provided, the callback function is called with label and the subject.
A retryable query that calls the given constructor function using the new keyword and the current subject as argument.
cy.wrap('Jan 1, 2019')
// same as "new Date('Jan 1, 2019')"
.make(Date)
.invoke('getFullYear')
.should('equal', 2019)
If you want to construct multiple items by mapping over the items in the current subject, use the cy.mapMake(constructorFn) query.
const dates = ['Jan 1, 2019', 'Feb 2, 2020', 'Mar 3, 2021']
cy.wrap(dates)
.mapMake(Date)
.print()
.mapInvoke('getFullYear')
.should('deep.equal', [2019, 2020, 2021])
You can pass additional arguments
.mapMake(constructorFn, 1, 2, 3)
// for each item "x" inside the subject,
// the constructor will be called
// like "new constructorFn(x, 1, 2, 3)
A better cy.log: yields the value, intelligently stringifies values using % and string-format notation.
cy.wrap(42)
.print() // "42"
// and yields the value
.should('equal', 42)
// pass formatting string
cy.wrap(42).print('the answer is %d') // "the answer is 42"
cy.wrap({ name: 'Joe' }).print('person %o') // 'person {"name":"Joe"}'
// use {0} with dot notation, supported deep properties
// https://github.com/davidchambers/string-format
cy.wrap({ name: 'Joe' }).print('person name {0.name}') // "person name Joe"
// print the length of an array
cy.wrap(arr).print('array length {0.length}') // "array length ..."
// pass your own function to return formatted string
cy.wrap(arr).print((a) => `array with ${a.length} items`)
// if you return a non-string, it will attempt to JSON.stringify it
cy.wrap(arr).print((list) => list[2]) // JSON.stringify(arr[2])
See print.cy.js for more examples
Finds a single item in the subject. Assumes subject is an array or a jQuery object. Uses Lodash _.find method.
// using predicate function
const isThree = n => n === 3
// predicate function receives every item from the array
cy.wrap([...]).findOne(isThree).should('equal', 3)
// using partial known properties of an object
cy.wrap([...]).findOne({ name: 'Anna' }).should('have.property', 'name', 'Anna')
You can find one element from the jQuery subject
```js // find one element with exac
$ claude mcp add cypress-map \
-- python -m otcore.mcp_server <graph>