
Дополнительные команды запроса Cypress для V12+
Добавьте этот пакет в качестве зависимости DEV:
$ npm i -D cypress-map
# or using Yarn
$ yarn add -D cypress-map
Включите этот пакет в свою спецификацию или файл поддержки, чтобы использовать все пользовательские команды запросов
import 'cypress-map'Альтернатива: импортируйте только команды запроса, которые вам нужны:
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 ) Он работает как cy.then , но cy.apply(fn) - это команда запросов. Функция fn должна быть синхронной, чистой функцией, которая использует только аргумент субъекта и возвращает новое значение. Обратный вызов функции fn не может использовать cy -команды Cypress.
Вы можете передать дополнительные левые аргументы на функцию обратного вызова. Затем он ставит субъект как последний аргумент, прежде чем вызывать функцию:
cy . wrap ( 8 ) . apply ( Cypress . _ . subtract , 4 ) . should ( 'equal' , - 4 ) Без аргументов cy.applyRight работает так же, как cy.apply . Если вы передаете аргументы, то предмет плюс аргументы становятся аргументами для обратного вызова. Субъект находится в левой (первой) позиции
cy . wrap ( 8 ) . applyRight ( Cypress . _ . subtract , 4 ) . should ( 'equal' , 4 )
// same as
cy . wrap ( 8 )
. apply ( ( subject ) => Cypress . _ . subtract ( subject , 4 ) )
. should ( 'equal' , 4 )Иногда у вас есть обратный вызов, и вы знаете первые аргументы (ы), и вам просто нужно поставить субъект на последнюю позицию. Здесь вы можете частично применить известные аргументы к данному обратному обращению.
// 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 )Если текущий субъект является массивом или объектом jQuery, вы можете применить заданный обратный вызов с аргументами к первым элементу или элементу. Текущий субъект будет последним аргументом.
// cy.applyToFirst(callback, ...args)
cy . wrap ( Cypress . $ ( '<div>100</div><div>200</div>' ) )
. applyToFirst ( ( base , el ) => parseInt ( el . innerText , base ) , 10 )
. should ( 'equal' , 100 )Если текущий субъект является массивом или объектом jQuery, вы можете применить заданный обратный вызов с аргументами к первым элементу или элементу. Текущий субъект будет первым аргументом.
// cy.applyToFirstRight(callback, ...args)
cy . wrap ( Cypress . $ ( '<div>100</div><div>200</div>' ) )
. applyToFirstRight ( ( el , base ) => parseInt ( el . innerText , base ) , 10 )
. should ( 'equal' , 100 )Нам часто просто нужно вызвать метод на первом элементе / элементе в текущем предмете
cy . get ( selector ) . invokeFirst ( 'getBoundingClientRect' )
// compute the vertical center for exampleПреобразует каждый объект в данной коллекции, проведя его через заданную функцию обратного вызова. Может также составить отображение каждого объекта с его свойством. Объектом может быть массивом или объектом jQuery.
// 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' ] ) Вы даже можете отобразить свойства объекта, перечисляя обратные вызовы. Например, давайте преобразуем age свойство из строки в число
cy . wrap ( {
age : '42' ,
lucky : true ,
} )
. map ( {
age : Number ,
} )
. should ( 'deep.equal' , {
age : 42 ,
lucky : true ,
} )Вы можете избежать любого преобразования, чтобы просто выбрать список свойств из объекта
const person = {
name : 'Joe' ,
age : 21 ,
occupation : 'student' ,
}
cy . wrap ( person ) . map ( [ 'name' , 'age' ] ) . should ( 'deep.equal' , {
name : 'Joe' ,
age : 21 ,
} )Вы можете извлечь вложенные пути с помощью «». в вашем пути
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' ] ) 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Вы можете предоставить начальное значение аккумулятора
cy . wrap ( [ 1 , 2 , 3 ] )
. reduce ( ( sum , n ) => sum + n , 10 )
. should ( 'equal' , 16 )См. Уменьшить.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' )УВЕДОМЛЕНИЕ: Если этикетка предоставлена, функция обратного вызова вызывается с меткой и субъектом.
Повторяемый запрос, который вызывает заданную функцию конструктора, используя new ключевое слово и текущий субъект в качестве аргумента.
cy . wrap ( 'Jan 1, 2019' )
// same as "new Date('Jan 1, 2019')"
. make ( Date )
. invoke ( 'getFullYear' )
. should ( 'equal' , 2019 ) Лучший cy.log : дает значение, разумно строит значения, используя % и нотации в виде строкости.
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])См. Print.cy.js для получения дополнительной информации
Находит один предмет в тему. Предполагается, что субъект - это массив или объект jQuery. Использует метод Lodash _.find .
// using predicate function
const isThree = n => n === 3
cy . wrap ( [ ... ] ) . findOne ( isThree ) . should ( 'equal' , 3 )
// using partial known properties of an object
cy . wrap ( [ ... ] ) . findOne ( { name : 'Anna' } ) . should ( 'have.property' , 'name' , 'Anna' )См. Find-One.cy.js
cy . get ( '.matching' )
. map ( 'innerText' )
. primo ( )
. invoke ( 'toUpperCase' )
. should ( 'equal' , 'FIRST' )Смотрите primo.cy.js
Работает как cy.its для объектов, но получает свойство для объектов cy.its , которые не имеют
cy . get ( '#items li.matching' )
. last ( )
. prop ( 'ariaLabel' )
. should ( 'equal' , 'four' )См. Prop.cy.js
Изменяет одно свойство внутри субъекта, проведя его через заданную функцию обратного вызова. Например, полезно для преобразования типа, давайте преобразуем свойство «возраст» в число
cy . wrap ( { age : '20' } )
. update ( 'age' , Number )
. should ( 'deep.equal' , { age : 20 } ) Возвращает элемент DOM из объекта jQuery в позиции k . Возвращает предмет из массива в позиции k . Для негативного индекса подсчитывает элементы с конца.
cy . get ( '#items li' ) . at ( - 1 ) . its ( 'innerText' ) . should ( 'equal' , 'fifth' )Смотрите at.cy.js
Возвращает случайно собранный элемент или элемент из текущего субъекта
cy . get ( '#items li' ) . sample ( ) . should ( 'have.text' , 'four' )Если вы передаете положительное число, то он выбирает несколько элементов или элементов
// yields jQuery object with 3 random items
cy . get ( '#items li' ) . sample ( 3 ) . should ( 'have.length' , 3 )См. Sample.cy.js
Дает второй элемент от текущего субъекта. Может быть элемент или элемент массива.
cy . get ( '#items li' ) . second ( ) . should ( 'have.text' , 'second' )См. Second.cy.js
Дает третий элемент от текущего субъекта. Может быть элемент или элемент массива.
cy . get ( '#items li' ) . third ( ) . should ( 'have.text' , 'third' )Смотрите Third.cy.js
Сохраняет текущий субъект в объекте Cypress.env . ПРИМЕЧАНИЕ. Объект Cypress.ENV сбрасывается перед запуском спецификации, но измененные значения передаются из теста на тест. Таким образом, вы можете легко перенести значение от первого теста до второго.
it ( 'saves value in this test' , ( ) => {
cy . wrap ( 'hello, world' ) . asEnv ( 'greeting' )
} )
it ( 'saved value is available in this test' , ( ) => {
expect ( Cypress . env ( 'greeting' ) , 'greeting' ) . to . equal ( 'hello, world' )
} )Вы действительно хотите, чтобы тесты зависели друг от друга?
Запрашивает страницу, используя несколько селекторов и возвращает найденные элементы в указанном порядке, независимо от того, как они заказаны в документе. Понимает, если кто -либо из селекторов не найден.
cy . getInOrder ( 'selector1' , 'selector2' , 'selector3' , ... )
// yields a single jQuery subject with
// elements for selector1
// and selector2,
// and selector3, etcВы также можете использовать один массив селекторных строк
cy . getInOrder ( [ 'h1' , 'h2' , 'h3' ] ) Иногда вы просто хотите подождать, пока элемент не станет стабильным. Например, если текстовое содержимое элемента не изменяется для N Milliseconds, то мы можем считать элемент text .
cy . get ( '#message' ) . stable ( 'text' )
// yields the element Поддерживаемые типы: text , value (для входных элементов), css и element (сравнивает ссылку на элемент)
Вы можете контролировать тихой период (миллисекунд) и передать log и варианты timeout
// stable for 500ms
// without logging
// with maximum retries duration of 6 seconds
cy . get ( '#message' ) . stable ( 'text' , 500 , { log : false , timeout : 6_000 } )При проверке свойства CSS быть стабильной, предоставьте название свойства:
// retries until the CSS animation finishes
// and the background color is red
cy . get ( '#message' )
. stable ( 'css' , 'background-color' , 100 )
// yields the element
. should ( 'have.css' , 'background-color' , 'rgb(255, 0, 0)' )См. Stable.cy.js и stable-css.cy.js
экспериментальный
Понимает до тех пор, пока элемент с данным селектором не отрывается от DOM.
cy . contains ( 'Click to re-render' ) . click ( )
cy . detaches ( '#list' ) Иногда отряд может происходить правильно с действием, и cy.detaches(selector) слишком поздно . Если бы вы знаете, что отряд уже мог бы произойти, вам нужно подготовиться к нему, используя псевдоним, хранящийся в объекте Cypress.env :
cy . get ( '#name2' ) . asEnv ( 'name' )
cy . contains ( 'Click to remove Joe' ) . click ( )
cy . detaches ( '@name' ) Объект jQuery будет храниться внутри Cypress.env под свойством name .
Смотрите Destach.cy.js
Вычисляет объект/массивы разницы с текущим объектом субъекта/массива.
cy . wrap ( { name : 'Joe' , age : 20 } )
. difference ( { name : 'Joe' , age : 30 } )
. should ( 'deep.equal' , { age : { actual : 20 , expected : 30 } } )Вы можете использовать функции синхронного предиката для проверки свойств
// confirm the value of the "age" property
// is larger than 15
. difference ( { name : 'Joe' , age : ( n ) => n > 15 } )Отчеты отсутствуют и дополнительные свойства. Смотрите разницу.cy.js
Примечание. have.length
// let's check if there are 3 objects in the array
// INSTEAD OF THIS
. difference ( [ Cypress . _ . object , Cypress . _ . object , Cypress . _ . object ] )
// USE AN ASSERTION
. should ( 'have.length' , 3 )Вы можете проверить каждый элемент в субъекте массива, используя значения / предикаты из ожидаемого объекта.
// list of people objects
cy . wrap ( people )
. difference ( {
name : Cypress . _ . isString ,
age : ( age ) => age > 1 && age < 100 ,
} )
. should ( 'be.empty' ) Чтобы узнать больше о команде cy.table , прочитайте тест на блог Test HTML -таблицы, используя команду Cy.Table запроса.
Извлекает все ячейки из текущей таблицы субъектов. Дает 2 -й массив струн.
cy . get ( 'table' ) . table ( ) Вы можете нарезать таблицу, чтобы дать только область .table(x, y, w, h)

Например, вы можете получить 2 на 2 субрегиона
cy . get ( 'table' )
. table ( 0 , 2 , 2 , 2 )
. should ( 'deep.equal' , [
[ 'Cary' , '30' ] ,
[ 'Joe' , '28' ] ,
] )См. Spec Table.cy.js для получения дополнительных примеров.
Совет: вы можете объединить cy.table с cy.map , cy.mapInvoke , чтобы получить части таблицы. Например, та же самая часть таблицы может быть извлечена с помощью:
cy . get ( 'table' )
. table ( )
. invoke ( 'slice' , 2 , 4 )
. mapInvoke ( 'slice' , 0 , 2 )
. should ( 'deep.equal' , [
[ 'Cary' , '30' ] ,
[ 'Joe' , '28' ] ,
] ) Совет 2: Чтобы получить только строку заголовков, объединить .table и .its
cy . get ( 'table' )
. table ( 0 , 0 , 3 , 1 )
. its ( 0 )
. should ( 'deep.equal' , [ 'Name' , 'Age' , 'Date (YYYY-MM-DD)' ] )Чтобы получить последний ряд, вы могли бы сделать:
cy . get ( 'table' ) . table ( ) . invoke ( 'slice' , - 1 ) . its ( 0 )Чтобы получить первый столбец, соединенный в один массив (вместо массива 1x1 массивов)
cy . get ( 'table' )
. table ( 0 , 1 , 1 ) // skip the heading "Name" cell
// combine 1x1 arrays into one array
. invoke ( 'flatMap' , Cypress . _ . identity )
. should ( 'deep.equal' , [ 'Dave' , 'Cary' , 'Joe' , 'Anna' ] ) Запрос для преобразования специальных объектов DOM в простые объекты. Например, для преобразования экземпляра DOMStringMap в простой объект, совместимый с deep.equal Apporting, мы можем сделать
cy . get ( 'article' )
. should ( 'have.prop' , 'dataset' )
. toPlainObject ( )
. should ( 'deep.equal' , {
columns : '3' ,
indexNumber : '12314' ,
parent : 'cars' ,
} ) По умолчанию использует json stringify и warse обратно. Если вы хотите преобразовать использование entries и fromEntries , добавьте аргумент:
cy . wrap ( new URLSearchParams ( searchParams ) ) . toPlainObject ( 'entries' ) В Cypress V12 cy.invoke стал запросом, который сделал работу с асинхронными методами действительно громоздкими. cy.invokeOnce - это возврат старый способ вызвать метод и дать разрешенное значение.
cy . wrap ( app )
// app.fetchName is an asynchronous method
// that returns a Promise
. invokeOnce ( 'fetchName' )
. should ( 'equal' , 'My App' )См. Spec invoke-once.cy.js для получения дополнительной информации.
Вот несколько примеров, чтобы уточнить различные команды запросов cy.invoke , cy.map и cy.mapInvoke , см. Diff.cy.js
const list = [ 'apples' , 'plums' , 'bananas' ]
// cy.invoke
cy . wrap ( list )
// calls ".sort()" on the list
. invoke ( 'sort' )
. should ( 'deep.equal' , [ 'apples' , 'bananas' , 'plums' ] )
// cy.mapInvoke
cy . wrap ( list )
// calls ".toUpperCase()" on every string in the list
. mapInvoke ( 'toUpperCase' )
. should ( 'deep.equal' , [ 'APPLES' , 'PLUMS' , 'BANANAS' ] )
// cy.map
const reverse = ( s ) => s . split ( '' ) . reverse ( ) . join ( '' )
cy . wrap ( list )
// reverses each string in the list
. map ( reverse )
. should ( 'deep.equal' , [ 'selppa' , 'smulp' , 'sananab' ] )
// grabs the "length" property from each string
. map ( 'length' )
. should ( 'deep.equal' , [ 6 , 5 , 7 ] ) Я добавил еще одну полезную команду (не запрос!) В этот пакет. Это позволяет обрабатывать элементы в субъекте массива один за другим через синхронные, асинхронные или cy -командные функции. Это связано с тем, что общее решение для извлечения элементов с использованием cy.each , например, не работает:
// fetch the users from a list of ids
// DOES NOT WORK
cy . get ( ids ) . each ( id => cy . request ( '/users/' + id ) ) . then ( users => ... )
// Nope, the yielded "users" result is ... still the "ids" subject
// ✅ CORRECT SOLUTION
cy . get ( ids ) . mapChain ( id => cy . request ( '/users/' + id ) ) . then ( users => ... ) Этот пакет включает в себя определения команд TypeScript для своих пользовательских команд в командах файла/index.d.ts. Чтобы использовать его из ваших спецификаций JavaScript:
/// <reference types="cypress-map" />Если вы используете TypeScript, включите этот модуль в свой список типов
{
"compilerOptions" : {
"types" : [ " cypress " , " cypress-map " ]
}
} Исходный код находится в папке SRC/Commands. Команда сборки создает код ES5, который входит в папку commands (не следует проверять в элементе управления исходным кодом). package.json commands src/commands/index.d.ts
should(callback) на лету. Примечание. Этот модуль не имеет метода filter , потому что Cypress API имеет команды запроса cy.filter и cy.invoke, которые вы можете использовать для фильтрации элементов в объекте jQuery или элементах в массиве. См. Примеры в Filter.cy.js Spec. Смотрите элементы видео фильтра и элементы с помощью повторных поисков.
Автор: Gleb Bahmutov <[email protected]> © 2022
Лицензия: MIT - делайте что -нибудь с кодом, но не вините меня, если она не работает.
Поддержка: если вы найдете какие -либо проблемы с этим модулем, электронная почта / твит / открытая проблема на GitHub