Perintah kueri Cypress Extra untuk v12+
Tambahkan paket ini sebagai ketergantungan dev:
$ npm i -D cypress-map
# or using Yarn
$ yarn add -D cypress-map
Sertakan paket ini dalam spek atau file dukungan Anda untuk menggunakan semua perintah kueri khusus
import 'cypress-map'
Alternatif: Impor hanya perintah kueri yang Anda butuhkan:
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 )
Ini berfungsi seperti cy.then
tapi cy.apply(fn)
adalah perintah kueri. Fungsi fn
harus sinkron, fungsi murni yang hanya menggunakan argumen subjek dan mengembalikan nilai baru fungsi callback fn
tidak dapat menggunakan perintah cypress apa pun cy
.
Anda dapat meneruskan argumen kiri tambahan ke fungsi panggilan balik. Kemudian menempatkan subjek sebagai argumen terakhir sebelum memanggil fungsi:
cy . wrap ( 8 ) . apply ( Cypress . _ . subtract , 4 ) . should ( 'equal' , - 4 )
Tanpa argumen, cy.applyRight
bekerja sama dengan cy.apply
. Jika Anda lulus argumen, maka subjek ditambah argumen menjadi argumen untuk panggilan balik. Subjek berada di posisi kiri (pertama)
cy . wrap ( 8 ) . applyRight ( Cypress . _ . subtract , 4 ) . should ( 'equal' , 4 )
// same as
cy . wrap ( 8 )
. apply ( ( subject ) => Cypress . _ . subtract ( subject , 4 ) )
. should ( 'equal' , 4 )
Terkadang Anda memiliki panggilan balik untuk diterapkan, dan Anda tahu argumen pertama, dan hanya perlu menempatkan subjek pada posisi terakhir. Di sinilah Anda dapat menerapkan sebagian argumen yang diketahui ke panggilan balik yang diberikan.
// 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 )
Jika subjek saat ini adalah array, atau objek jQuery, Anda dapat menerapkan panggilan balik yang diberikan dengan argumen ke item atau elemen pertama . Subjek saat ini akan menjadi argumen terakhir .
// cy.applyToFirst(callback, ...args)
cy . wrap ( Cypress . $ ( '<div>100</div><div>200</div>' ) )
. applyToFirst ( ( base , el ) => parseInt ( el . innerText , base ) , 10 )
. should ( 'equal' , 100 )
Jika subjek saat ini adalah array, atau objek jQuery, Anda dapat menerapkan panggilan balik yang diberikan dengan argumen ke item atau elemen pertama . Subjek saat ini akan menjadi argumen pertama .
// cy.applyToFirstRight(callback, ...args)
cy . wrap ( Cypress . $ ( '<div>100</div><div>200</div>' ) )
. applyToFirstRight ( ( el , base ) => parseInt ( el . innerText , base ) , 10 )
. should ( 'equal' , 100 )
Kita sering hanya perlu memanggil metode pada elemen / item pertama dalam subjek saat ini
cy . get ( selector ) . invokeFirst ( 'getBoundingClientRect' )
// compute the vertical center for example
Mengubah setiap objek dalam koleksi yang diberikan dengan menjalankannya melalui fungsi panggilan balik yang diberikan. Dapat juga memetakan setiap objek ke propertinya. Objek bisa berupa array atau objek 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' ] )
Anda bahkan dapat memetakan properti suatu objek dengan mencantumkan panggilan balik. Misalnya, mari kita mengonversi properti age
dari string ke angka
cy . wrap ( {
age : '42' ,
lucky : true ,
} )
. map ( {
age : Number ,
} )
. should ( 'deep.equal' , {
age : 42 ,
lucky : true ,
} )
Anda dapat menghindari konversi apa pun untuk cukup memilih daftar properti dari suatu objek
const person = {
name : 'Joe' ,
age : 21 ,
occupation : 'student' ,
}
cy . wrap ( person ) . map ( [ 'name' , 'age' ] ) . should ( 'deep.equal' , {
name : 'Joe' ,
age : 21 ,
} )
Anda dapat mengekstrak jalur bersarang dengan menggunakan "." di jalur properti Anda
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
Anda dapat memberikan nilai akumulator awal
cy . wrap ( [ 1 , 2 , 3 ] )
. reduce ( ( sum , n ) => sum + n , 10 )
. should ( 'equal' , 16 )
Lihat 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' )
PEMBERITAHUAN: Jika label disediakan, fungsi callback dipanggil dengan label dan subjek.
Kueri yang dapat dikembalikan yang memanggil fungsi konstruktor yang diberikan menggunakan kata kunci new
dan subjek saat ini sebagai argumen.
cy . wrap ( 'Jan 1, 2019' )
// same as "new Date('Jan 1, 2019')"
. make ( Date )
. invoke ( 'getFullYear' )
. should ( 'equal' , 2019 )
cy.log
yang lebih baik: menghasilkan nilainya, secara cerdas merendahkan nilai menggunakan %
dan notasi format string.
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])
Lihat print.cy.js untuk contoh lebih lanjut
Menemukan satu item dalam subjek. Mengasumsikan subjek adalah array atau objek jQuery. Menggunakan Lodash _.find
Method.
// 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' )
Lihat find-one.cy.js
cy . get ( '.matching' )
. map ( 'innerText' )
. primo ( )
. invoke ( 'toUpperCase' )
. should ( 'equal' , 'FIRST' )
Lihat Primo.cy.js
Bekerja seperti cy.its
untuk objek, tetapi mendapatkan properti untuk objek jQuery, yang tidak dilakukan cy.its
cy . get ( '#items li.matching' )
. last ( )
. prop ( 'ariaLabel' )
. should ( 'equal' , 'four' )
Lihat Prop.cy.js
Mengubah satu properti di dalam subjek dengan menjalankannya melalui fungsi panggilan balik yang diberikan. Berguna untuk melakukan konversi ketik, misalnya, mari kita mengonversi properti "usia" ke nomor
cy . wrap ( { age : '20' } )
. update ( 'age' , Number )
. should ( 'deep.equal' , { age : 20 } )
Mengembalikan elemen DOM dari objek jQuery pada posisi k
. Mengembalikan item dari array pada posisi k
. Untuk indeks negatif, menghitung item dari akhir.
cy . get ( '#items li' ) . at ( - 1 ) . its ( 'innerText' ) . should ( 'equal' , 'fifth' )
Lihat di.cy.js
Mengembalikan item atau elemen yang dipilih secara acak dari subjek saat ini
cy . get ( '#items li' ) . sample ( ) . should ( 'have.text' , 'four' )
Jika Anda memberikan angka positif, maka ia memilih beberapa elemen atau item
// yields jQuery object with 3 random items
cy . get ( '#items li' ) . sample ( 3 ) . should ( 'have.length' , 3 )
Lihat sampel.cy.js
Menghasilkan elemen kedua dari subjek saat ini. Bisa berupa elemen atau item array.
cy . get ( '#items li' ) . second ( ) . should ( 'have.text' , 'second' )
Lihat Second.cy.js
Menghasilkan elemen ketiga dari subjek saat ini. Bisa berupa elemen atau item array.
cy . get ( '#items li' ) . third ( ) . should ( 'have.text' , 'third' )
Lihat ketiga.cy.js
Menyimpan subjek saat ini di objek Cypress.env
. Catatan: Objek Cypress.env diatur ulang sebelum spec berjalan, tetapi nilai yang diubah diteruskan dari tes ke tes. Dengan demikian Anda dapat dengan mudah memberikan nilai dari tes pertama ke yang kedua.
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' )
} )
Apakah Anda benar -benar ingin membuat tes bergantung satu sama lain?
Permintaan halaman menggunakan beberapa pemilih dan mengembalikan elemen yang ditemukan dalam urutan yang ditentukan , tidak peduli bagaimana mereka dipesan dalam dokumen. Menggantung kembali jika ada penyeleksi yang tidak ditemukan.
cy . getInOrder ( 'selector1' , 'selector2' , 'selector3' , ... )
// yields a single jQuery subject with
// elements for selector1
// and selector2,
// and selector3, etc
Anda juga dapat menggunakan serangkaian string pemilih tunggal
cy . getInOrder ( [ 'h1' , 'h2' , 'h3' ] )
Terkadang Anda hanya ingin menunggu sampai elemen stabil. Misalnya, jika konten teks elemen tidak berubah selama n milidetik, maka kita dapat menganggap elemen sebagai text
stabil.
cy . get ( '#message' ) . stable ( 'text' )
// yields the element
Jenis yang Didukung: text
, value
(untuk Elemen Input), css
, dan element
(membandingkan referensi elemen)
Anda dapat mengontrol periode tenang (milidetik), dan lulus log
dan opsi timeout
// stable for 500ms
// without logging
// with maximum retries duration of 6 seconds
cy . get ( '#message' ) . stable ( 'text' , 500 , { log : false , timeout : 6_000 } )
Saat memeriksa properti CSS stabil, berikan nama properti:
// 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)' )
Lihat stabil.cy.js dan stabil-css.cy.js
Eksperimental
Retries sampai elemen dengan pemilih yang diberikan terlepas dari DOM.
cy . contains ( 'Click to re-render' ) . click ( )
cy . detaches ( '#list' )
Kadang -kadang detasemen dapat terjadi dengan benar dengan tindakan dan cy.detaches(selector)
sudah terlambat . Jika Anda tahu detasemen mungkin sudah terjadi, Anda perlu mempersiapkannya dengan menggunakan alias yang disimpan di objek Cypress.env
:
cy . get ( '#name2' ) . asEnv ( 'name' )
cy . contains ( 'Click to remove Joe' ) . click ( )
cy . detaches ( '@name' )
Objek jQuery akan disimpan di dalam Cypress.env
di bawah properti name
.
Lihat detach.cy.js
Menghitung objek/array dari perbedaan dengan objek/array subjek saat ini.
cy . wrap ( { name : 'Joe' , age : 20 } )
. difference ( { name : 'Joe' , age : 30 } )
. should ( 'deep.equal' , { age : { actual : 20 , expected : 30 } } )
Anda dapat menggunakan fungsi predikat sinkron untuk memvalidasi sifat
// confirm the value of the "age" property
// is larger than 15
. difference ( { name : 'Joe' , age : ( n ) => n > 15 } )
Melaporkan properti yang hilang dan ekstra. Lihat perbedaan.cy.js
Catatan: Gunakan have.length
untuk memvalidasi jumlah item dalam array:
// 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 )
Anda dapat memeriksa setiap item dalam subjek array menggunakan nilai / predikat dari objek yang diharapkan.
// list of people objects
cy . wrap ( people )
. difference ( {
name : Cypress . _ . isString ,
age : ( age ) => age > 1 && age < 100 ,
} )
. should ( 'be.empty' )
Untuk mempelajari lebih lanjut tentang perintah cy.table
, baca tabel tes html posting blog menggunakan perintah kueri cy.table.
Mengekstrak semua sel dari tabel subjek saat ini. Menghasilkan serangkaian string 2D.
cy . get ( 'table' ) . table ( )
Anda dapat mengiris meja untuk menghasilkan hanya suatu wilayah .table(x, y, w, h)
Misalnya, Anda bisa mendapatkan 2 dengan 2 subregion
cy . get ( 'table' )
. table ( 0 , 2 , 2 , 2 )
. should ( 'deep.equal' , [
[ 'Cary' , '30' ] ,
[ 'Joe' , '28' ] ,
] )
Lihat spec tabel.cy.js untuk lebih banyak contoh.
Tip: Anda dapat menggabungkan cy.table
dengan cy.map
, cy.mapInvoke
untuk mendapatkan bagian -bagian tabel. Misalnya, bagian 2x2 yang sama dari tabel dapat diekstraksi dengan:
cy . get ( 'table' )
. table ( )
. invoke ( 'slice' , 2 , 4 )
. mapInvoke ( 'slice' , 0 , 2 )
. should ( 'deep.equal' , [
[ 'Cary' , '30' ] ,
[ 'Joe' , '28' ] ,
] )
Tip 2: Untuk mendapatkan baris headings saja, gabungkan .table
dan .its
pertanyaan
cy . get ( 'table' )
. table ( 0 , 0 , 3 , 1 )
. its ( 0 )
. should ( 'deep.equal' , [ 'Name' , 'Age' , 'Date (YYYY-MM-DD)' ] )
Untuk mendapatkan baris terakhir, Anda bisa melakukannya:
cy . get ( 'table' ) . table ( ) . invoke ( 'slice' , - 1 ) . its ( 0 )
Untuk mendapatkan kolom pertama bergabung dalam satu array (bukan array array 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' ] )
Kueri untuk mengubah objek DOM khusus menjadi objek biasa. Misalnya, untuk mengubah instance DOMStringMap
menjadi objek polos yang kompatibel dengan deep.equal
cy . get ( 'article' )
. should ( 'have.prop' , 'dataset' )
. toPlainObject ( )
. should ( 'deep.equal' , {
columns : '3' ,
indexNumber : '12314' ,
parent : 'cars' ,
} )
Secara default menggunakan JSON Stringify dan Parse Back. Jika Anda ingin mengonversi menggunakan entries
dan fromEntries
, tambahkan argumen:
cy . wrap ( new URLSearchParams ( searchParams ) ) . toPlainObject ( 'entries' )
Di Cypress v12 cy.invoke
menjadi kueri, yang membuat bekerja dengan metode asinkron benar -benar sulit. cy.invokeOnce
adalah pengembalian cara lama untuk memanggil metode dan menghasilkan nilai yang diselesaikan.
cy . wrap ( app )
// app.fetchName is an asynchronous method
// that returns a Promise
. invokeOnce ( 'fetchName' )
. should ( 'equal' , 'My App' )
Lihat spek Invoke-Nce.cy.js untuk lebih banyak contoh.
Berikut adalah beberapa contoh untuk mengklarifikasi perbedaan antara perintah kueri cy.invoke
, cy.map
, dan cy.mapInvoke
, lihat 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 ] )
Saya telah menambahkan perintah lain yang berguna (bukan kueri!) Ke paket ini. Ini memungkinkan Anda untuk memproses item dalam subjek array satu per satu melalui fungsi perintah sinkron, asinkron, atau cy
. Ini karena solusi umum untuk mengambil item menggunakan cy.each
, misalnya tidak berfungsi:
// 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 => ... )
Paket ini mencakup definisi perintah TypeScript untuk perintah kustomnya di perintah file/index.d.ts. Untuk menggunakannya dari spesifikasi javascript Anda:
/// <reference types="cypress-map" />
Jika Anda menggunakan TypeScript, sertakan modul ini dalam daftar tipe Anda
{
"compilerOptions" : {
"types" : [ " cypress " , " cypress-map " ]
}
}
Kode sumber ada di folder SRC/Commands. Perintah build menghasilkan kode ES5 yang masuk ke folder commands
(tidak boleh diperiksa ke kontrol kode sumber). package.json
dalam distribusi NPM termasuk commands
ditambah jenis dari file src/commands/index.d.ts
.
should(callback)
dengan cepat. Catatan: Modul ini tidak memiliki metode filter
karena Cypress API memiliki perintah kueri Cy.filter dan cy.invoke yang dapat Anda gunakan untuk memfilter elemen dalam objek atau item jQuery dalam array. Lihat contoh dalam spesifikasi filter.cy.js. Lihat elemen dan item filter video dengan retries.
Penulis: Gleb Bahmutov <[email protected]> © 2022
Lisensi: MIT - Lakukan apapun dengan kode, tetapi jangan salahkan saya jika tidak berhasil.
Dukungan: Jika Anda menemukan masalah dengan modul ini, email / tweet / buka masalah di github