
Zusätzliche Zypressen -Abfragenbefehle für v12+
Fügen Sie dieses Paket als Entwicklerabhängigkeit hinzu:
$ npm i -D cypress-map
# or using Yarn
$ yarn add -D cypress-map
Fügen Sie dieses Paket in Ihre Spezifikation oder Support -Datei ein, um alle benutzerdefinierten Abfragenbefehle zu verwenden
import 'cypress-map'Alternative: Importieren Sie nur die von Ihnen benötigten Abfragebefehle:
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 ) Es funktioniert wie cy.then aber cy.apply(fn) ist ein Abfragebefehl. Funktion fn fn synchron sein, reine Funktion, die nur das Subjektargument verwendet und einen neuen Wert zurückgibt cy
Sie können zusätzliche linke Argumente an die Rückruffunktion weitergeben. Dann wird das Thema als das letzte Argument vorgenommen, bevor er die Funktion aufruft:
cy . wrap ( 8 ) . apply ( Cypress . _ . subtract , 4 ) . should ( 'equal' , - 4 ) Ohne Argumente funktioniert cy.applyRight genauso wie cy.apply . Wenn Sie Argumente verabschieden, werden das Thema plus die Argumente zu den Argumenten zum Rückruf. Das Subjekt befindet sich links (erster) 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 )Manchmal haben Sie den Rückruf zu bewerben und kennen die ersten Argumente (n) und müssen das Thema nur an die letzte Position bringen. Hier können Sie die bekannten Argumente teilweise auf den angegebenen Rückruf anwenden.
// 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 )Wenn es sich bei dem aktuellen Thema um ein Array oder ein JQuery -Objekt handelt, können Sie den angegebenen Rückruf mit Argumenten auf das erste Element oder Element anwenden. Das aktuelle Thema wird das letzte Argument sein.
// cy.applyToFirst(callback, ...args)
cy . wrap ( Cypress . $ ( '<div>100</div><div>200</div>' ) )
. applyToFirst ( ( base , el ) => parseInt ( el . innerText , base ) , 10 )
. should ( 'equal' , 100 )Wenn es sich bei dem aktuellen Thema um ein Array oder ein JQuery -Objekt handelt, können Sie den angegebenen Rückruf mit Argumenten auf das erste Element oder Element anwenden. Das aktuelle Thema wird das erste Argument sein.
// cy.applyToFirstRight(callback, ...args)
cy . wrap ( Cypress . $ ( '<div>100</div><div>200</div>' ) )
. applyToFirstRight ( ( el , base ) => parseInt ( el . innerText , base ) , 10 )
. should ( 'equal' , 100 )Wir müssen oft nur eine Methode für das erste Element / Element im aktuellen Thema aufrufen
cy . get ( selector ) . invokeFirst ( 'getBoundingClientRect' )
// compute the vertical center for exampleVerwandelt jedes Objekt in der angegebenen Sammlung, indem Sie es durch die angegebene Rückruffunktion ausführen. Kann auch jedes Objekt seiner Eigenschaft zuordnen. Ein Objekt kann ein Array oder ein JQuery -Objekt sein.
// 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' ] ) Sie können sogar Eigenschaften eines Objekts durch Auflisten von Rückrufen abbilden. Lassen Sie uns beispielsweise die age von einer Zeichenfolge in eine Zahl konvertieren
cy . wrap ( {
age : '42' ,
lucky : true ,
} )
. map ( {
age : Number ,
} )
. should ( 'deep.equal' , {
age : 42 ,
lucky : true ,
} )Sie können jede Konvertierung vermeiden, um einfach die Liste der Eigenschaften aus einem Objekt auszuwählen
const person = {
name : 'Joe' ,
age : 21 ,
occupation : 'student' ,
}
cy . wrap ( person ) . map ( [ 'name' , 'age' ] ) . should ( 'deep.equal' , {
name : 'Joe' ,
age : 21 ,
} )Sie können verschachtelte Pfade mit "" -"extrahieren." in Ihrem Eigenschaftspfad
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 priceSie können den anfänglichen Akkumulatorwert angeben
cy . wrap ( [ 1 , 2 , 3 ] )
. reduce ( ( sum , n ) => sum + n , 10 )
. should ( 'equal' , 16 )Siehe record.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' )Hinweis: Wenn das Etikett bereitgestellt wird, wird die Rückruffunktion mit Etikett und dem Thema aufgerufen.
Eine Wiederholungsabfrage, die die angegebene Konstruktorfunktion mit dem new Schlüsselwort und dem aktuellen Thema als Argument aufruft.
cy . wrap ( 'Jan 1, 2019' )
// same as "new Date('Jan 1, 2019')"
. make ( Date )
. invoke ( 'getFullYear' )
. should ( 'equal' , 2019 ) Ein besseres cy.log : Ergibt den Wert, intelligent Stringwerte mit % und 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])Weitere Beispiele finden Sie unter print.cy.js
Findet im Thema einen einzelnen Element. Angenommen, das Thema ist ein Array oder ein JQuery -Objekt. Verwendet die Lodash _.find -Methode.
// 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' )Siehe Find-One.cy.js
cy . get ( '.matching' )
. map ( 'innerText' )
. primo ( )
. invoke ( 'toUpperCase' )
. should ( 'equal' , 'FIRST' )Siehe primo.cy.js
Funktioniert wie cy.its für Objekte, erhält die Eigenschaft für JQuery -Objekte, die cy.its nicht tut
cy . get ( '#items li.matching' )
. last ( )
. prop ( 'ariaLabel' )
. should ( 'equal' , 'four' )Siehe prop.cy.js
Ändert eine einzelne Eigenschaft innerhalb des Subjekts, indem Sie sie durch die angegebene Rückruffunktion ausführen. Nützlich, um Conversions zu typern, wandeln wir beispielsweise die Eigenschaft "Alter" in eine Zahl um
cy . wrap ( { age : '20' } )
. update ( 'age' , Number )
. should ( 'deep.equal' , { age : 20 } ) Gibt ein DOM -Element von JQuery -Objekt an Position k zurück. Gibt einen Artikel von Array an Position k zurück. Für den negativen Index zählt die Elemente vom Ende.
cy . get ( '#items li' ) . at ( - 1 ) . its ( 'innerText' ) . should ( 'equal' , 'fifth' )Siehe at.cy.js
Gibt ein zufällig ausgewähltes Element oder Element aus dem aktuellen Thema zurück
cy . get ( '#items li' ) . sample ( ) . should ( 'have.text' , 'four' )Wenn Sie eine positive Zahl übergeben, wählt es mehrere Elemente oder Elemente aus
// yields jQuery object with 3 random items
cy . get ( '#items li' ) . sample ( 3 ) . should ( 'have.length' , 3 )Siehe Sample.cy.js
Ergibt das zweite Element aus dem aktuellen Thema. Könnte ein Element oder ein Array -Element sein.
cy . get ( '#items li' ) . second ( ) . should ( 'have.text' , 'second' )Siehe Second.cy.js
Ergibt das dritte Element aus dem aktuellen Thema. Könnte ein Element oder ein Array -Element sein.
cy . get ( '#items li' ) . third ( ) . should ( 'have.text' , 'third' )Siehe dritte.cy.js
Speichert das aktuelle Thema im Cypress.env -Objekt. HINWEIS: Cypress.Env -Objekt wird vor dem Spezifikationslauf zurückgesetzt, die geänderten Werte werden jedoch von der Test zu Test übergeben. So können Sie leicht einen Wert vom ersten Test zum zweiten übergeben.
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' )
} )Möchten Sie die Tests wirklich voneinander abhängen?
Fragen Sie die Seite mit mehreren Selektoren ab und geben die gefundenen Elemente in der angegebenen Reihenfolge zurück, unabhängig davon, wie sie im Dokument bestellt werden. Wiederholungen, wenn einer der Selektoren nicht gefunden wird.
cy . getInOrder ( 'selector1' , 'selector2' , 'selector3' , ... )
// yields a single jQuery subject with
// elements for selector1
// and selector2,
// and selector3, etcSie können auch ein einzelnes Array von Selektor -Zeichenfolgen verwenden
cy . getInOrder ( [ 'h1' , 'h2' , 'h3' ] ) Manchmal möchten Sie nur warten, bis das Element stabil ist. Wenn sich der Textinhalt des Elements beispielsweise für N -Millisekunden nicht ändert, können wir das Element als text betrachten.
cy . get ( '#message' ) . stable ( 'text' )
// yields the element Unterstützte Typen: text , value (für Eingabeelemente), css und element (vergleicht die Elementreferenz)
Sie können die Ruhezeit (Millisekunden) steuern und das log und die timeout übergeben
// stable for 500ms
// without logging
// with maximum retries duration of 6 seconds
cy . get ( '#message' ) . stable ( 'text' , 500 , { log : false , timeout : 6_000 } )Geben Sie beim stabilen Überprüfen der CSS -Eigenschaft den Namen der Eigenschaft an:
// 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)' )Siehe Stable.cy.js und Stable-css.cy.js
Experimental-
Wiederholt das Element mit dem angegebenen Selektor von DOM.
cy . contains ( 'Click to re-render' ) . click ( )
cy . detaches ( '#list' ) Manchmal kann die Ablösung mit der Aktion richtig erfolgen und die cy.detaches(selector) zu spät sind. Wenn Sie wissen, dass die Abteilung möglicherweise bereits passiert ist, müssen Sie sich darauf vorbereiten, indem Sie einen Alias verwenden, der im Cypress.env -Objekt gespeichert ist:
cy . get ( '#name2' ) . asEnv ( 'name' )
cy . contains ( 'Click to remove Joe' ) . click ( )
cy . detaches ( '@name' ) Das JQuery -Objekt wird in der Cypress.env unter der name -Eigenschaft gespeichert.
Siehe detach.cy.js
Berechnet ein Objekt/Arrays der Differenz mit dem aktuellen Subjektobjekt/-array.
cy . wrap ( { name : 'Joe' , age : 20 } )
. difference ( { name : 'Joe' , age : 30 } )
. should ( 'deep.equal' , { age : { actual : 20 , expected : 30 } } )Sie können synchrone Prädikatfunktionen verwenden, um Eigenschaften zu validieren
// confirm the value of the "age" property
// is larger than 15
. difference ( { name : 'Joe' , age : ( n ) => n > 15 } )Berichte fehlende und zusätzliche Eigenschaften. Siehe differenz.cy.js
HINWEIS: Verwenden Sie have.length um die Anzahl der Elemente in einem Array zu validieren:
// 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 )Sie können jedes Element im Array -Subjekt unter Verwendung von Werten / Prädikaten aus dem erwarteten Objekt überprüfen.
// list of people objects
cy . wrap ( people )
. difference ( {
name : Cypress . _ . isString ,
age : ( age ) => age > 1 && age < 100 ,
} )
. should ( 'be.empty' ) Um mehr über den Befehl cy.table zu erfahren, lesen Sie die HTML -Tabellen des Blog -Beitrags mit Cy.Table Query -Befehl.
Extrahiert alle Zellen aus der aktuellen Subjekttabelle. Ergibt eine 2D -Reihe von Saiten.
cy . get ( 'table' ) . table ( ) Sie können die Tabelle in Scheiben schneiden, um nur einen Region zu ergeben .table(x, y, w, h)

Zum Beispiel können Sie 2 mal 2 Subregion erhalten
cy . get ( 'table' )
. table ( 0 , 2 , 2 , 2 )
. should ( 'deep.equal' , [
[ 'Cary' , '30' ] ,
[ 'Joe' , '28' ] ,
] )Weitere Beispiele finden Sie in der technischen Tabelle.cy.js.
Tipp: Sie können cy.table mit cy.map , cy.mapInvoke kombinieren, um die Teile der Tabelle zu erhalten. Zum Beispiel könnte der gleiche 2x2 -Teil der Tabelle mit:
cy . get ( 'table' )
. table ( )
. invoke ( 'slice' , 2 , 4 )
. mapInvoke ( 'slice' , 0 , 2 )
. should ( 'deep.equal' , [
[ 'Cary' , '30' ] ,
[ 'Joe' , '28' ] ,
] ) Tipp 2: .its die Überschriftenreihe .table erhalten
cy . get ( 'table' )
. table ( 0 , 0 , 3 , 1 )
. its ( 0 )
. should ( 'deep.equal' , [ 'Name' , 'Age' , 'Date (YYYY-MM-DD)' ] )Um die letzte Reihe zu bekommen, könnten Sie:
cy . get ( 'table' ) . table ( ) . invoke ( 'slice' , - 1 ) . its ( 0 )Um die erste Spalte in ein einzelnes Array zu bringen (anstelle von Array von 1x1 -Arrays)
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' ] ) Eine Abfrage zum Umwandeln spezieller DOM -Objekte in einfache Objekte. Zum Beispiel um deep.equal DOMStringMap
cy . get ( 'article' )
. should ( 'have.prop' , 'dataset' )
. toPlainObject ( )
. should ( 'deep.equal' , {
columns : '3' ,
indexNumber : '12314' ,
parent : 'cars' ,
} ) Verwendet standardmäßig JSON Stringify und Parse zurück. Wenn Sie mithilfe von entries und fromEntries konvertieren möchten, fügen Sie ein Argument hinzu:
cy . wrap ( new URLSearchParams ( searchParams ) ) . toPlainObject ( 'entries' ) In Cypress V12 cy.invoke wurde eine Frage, die die Arbeit mit asynchronen Methoden wirklich unhandlich machte. Die cy.invokeOnce ist eine Rückgabe der alten Art, die Methode aufzurufen und den gelösten Wert zu ergeben.
cy . wrap ( app )
// app.fetchName is an asynchronous method
// that returns a Promise
. invokeOnce ( 'fetchName' )
. should ( 'equal' , 'My App' )Weitere Beispiele finden Sie in der Spec Incoke-once.cy.js.
Hier sind einige Beispiele, um die Unterschiede zwischen cy.invoke , cy.map und cy.mapInvoke -Query -Befehlen zu klären, siehe 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 ] ) Ich habe diesem Paket einen weiteren nützlichen Befehl (keine Abfrage!) Hinzugefügt. Sie können Elemente im Array -Subjekt nacheinander über synchrone, asynchrone oder cy -Befehlsfunktionen verarbeiten. Dies liegt daran, dass die gemeinsame Lösung für das Abrufen von Elementen mit cy.each beispielsweise nicht funktioniert:
// 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 => ... ) Dieses Paket enthält die Befehlsdefinitionen von TypeScript für seine benutzerdefinierten Befehle in den Dateibefehlen/index.d.ts. Um es aus Ihren JavaScript -Spezifikationen zu verwenden:
/// <reference types="cypress-map" />Wenn Sie TypeScript verwenden, geben Sie dieses Modul in Ihre Typ -Liste ein
{
"compilerOptions" : {
"types" : [ " cypress " , " cypress-map " ]
}
} Der Quellcode befindet sich im Ordner SRC/Befehl. Der Befehl Build erstellt ES5 -Code, der in den commands eingeht (sollte nicht in die Quellcode -Steuerung untersucht werden). Das package.json in seiner NPM -Verteilung enthält commands plus die Typen aus src/commands/index.d.ts Datei.
should(callback) im laufenden Fliegen haben. HINWEIS: Dieses Modul hat keine filter , da Cypress -API Abfragebefehle Cy.Filter und Cy.invoke enthält, mit denen Sie Elemente in einem JQuery -Objekt oder Elementen in einem Array filtern können. Siehe die Beispiele in filter.cy.js spec. Siehe Videofilterelemente und Elemente mit Wiederholungen.
Autor: Gleb Bahmutov <[email protected]> © 2022
Lizenz: MIT - Mach etwas mit dem Code, aber beschuldige mich nicht, wenn es nicht funktioniert.
Support: Wenn Sie Probleme mit diesem Modul finden, E -Mail / Tweet / Öffnen Sie das Problem auf GitHub