Usar cy.intercept()
para gestionar el comportamiento de las solicitudes HTTP en la capa de red.
Con cy.intercept()
, usted puede:
- stub o espiar cualquier tipo de solicitud HTTP.
- Si
cy.intercept()
proporciona un objeto de respuesta, o un accesorio, o llamareq.reply()
entonces la solicitud NO irá al servidor y, en su lugar, se burlará de la prueba. - De lo contrario, la solicitud se enviará al servidor y la prueba espiará la llamada de red. La intercepción de espionaje puede incluso modificar la respuesta real del servidor antes de que se devuelva a la aplicación web bajo prueba.
- Si
-
modificar el cuerpo, los encabezados y la URL de una solicitud HTTP antes de enviarla al servidor de destino.
- stub la respuesta a una solicitud HTTP, ya sea de forma dinámica o estática.
-
modificar las respuestas HTTP reales, cambiando el cuerpo, los encabezados o el código de estado HTTP antes de que sean recibidos por el navegador.
- y mucho más –
cy.intercept()
da acceso completo a todas las solicitudes HTTP en todas las etapas.
Comparación con cy.route()
A diferencia de cy.route (), cy.intercept()
:
- puede interceptar todo tipo de solicitudes de red, incluidas Fetch API, cargas de páginas, XMLHttpRequests, cargas de recursos, etc.
- no requiere llamar a cy.server () antes de su uso; de hecho,
cy.server()
no influyecy.intercept()
en absoluto. - no tiene un método establecido en
GET
por defecto, pero intercepta*
métodos.
Uso
cy.intercept(url, routeHandler?) cy.intercept(method, url, routeHandler?) cy.intercept(routeMatcher, routeHandler?) cy.intercept(url, routeMatcher, routeHandler)
Nota: todas las intersecciones se borran automáticamente antes de cada prueba.
Argumentos
url (string | RegExp
)
Especifique la URL para que coincida. Consulte los ejemplos de URL coincidentes para ver cómo se comparan las URL.
cy.intercept('http://example.com/widgets') cy.intercept('http://example.com/widgets', { fixture: 'widgets.json' })
método (string
)
Especifique el método HTTP para hacer coincidir.
cy.intercept('POST', 'http://example.com/widgets', { statusCode: 200, body: 'it worked!', })
routeMatcher (RouteMatcher
)
routeMatcher
es un objeto que se utiliza para hacer coincidir las solicitudes HTTP entrantes que serán manejadas por esta ruta.
Todas las propiedades son opcionales. Todas las propiedades establecidas deben coincidir para que la ruta maneje una solicitud. Si un string
se pasa a cualquier propiedad, se comparará globalmente con la solicitud utilizando minimatch
.El disponible routeMatcher
las propiedades se enumeran a continuación:
{ /** * Match against the username and password used in HTTP Basic authentication. */ auth?: { username: string | RegExp, password: string | RegExp } /** * Match against HTTP headers on the request. */ headers?: { [name: string]: string | RegExp } /** * Match against the requested HTTP hostname. */ hostname?: string | RegExp /** * If 'true', only HTTPS requests will be matched. * If 'false', only HTTP requests will be matched. */ https?: boolean /** * Match against the request's HTTP method. * @default '*' */ method?: string | RegExp /** * If `true`, this will pass the request on to the next `RouteMatcher` after the request handler completes. * Can only be used with a dynamic request handler. * @default false */ middleware?: boolean /** * Match on request path after the hostname, including query params. */ path?: string | RegExp /** * Matches like 'path', but without query params. */ pathname?: string | RegExp /** * Match based on requested port, or pass an array of ports * to match against any in that array. */ port?: number | number[] /** * Match on parsed querystring parameters. */ query?: { [key: string]: string | RegExp } /** * Match against the full request URL. */ url?: string | RegExp }
routeMatcher
ejemplos de uso:
cy.intercept({ pathname: '/search', query: { q: 'some terms', }, }).as('searchForTerms') // this 'cy.wait' will only resolve once a request is made to '/search' // with the query paramater 'q=some+terms' cy.wait('@searchForTerms') cy.intercept( { // this RegExp matches any URL beginning with 'http://api.example.com/widgets' url: /^http://api.example.com/widgets/, headers: { 'x-requested-with': 'exampleClient', }, }, (req) => { // only requests to URLs starting with 'http://api.example.com/widgets' // having the header 'x-requested-with: exampleClient' will be received } }) // in this example, the supplied URL `/users` is merged with the RouteMatcher // passed as the second argument cy.intercept('/users', { middleware: true }, (req) => { req.headers['authorization'] = `Bearer ${bearerToken}` })
routeHandler (string | object | Function | StaticResponse
)
los routeHandler
define lo que sucederá con una solicitud si routeMatcher coincide. Se puede usar para definir estáticamente una respuesta para solicitudes coincidentes, o se puede pasar una función para interceptar dinámicamente la solicitud saliente.
- Si un cuerda se pasa, las solicitudes a la ruta se cumplirán con esa cadena como cuerpo. Paso
"foo"
es equivalente a usar unStaticResponse
objeto con{ body: "foo" }
. - Si un
StaticResponse
objeto se pasa, las solicitudes a la ruta se cumplirán con una respuesta utilizando los valores proporcionados en elStaticResponse
. AStaticResponse
puede definir el cuerpo de la respuesta, así como los encabezados, el código de estado HTTP y más. Consulte Apuntar una respuesta con unStaticResponse
objeto para ver un ejemplo de cómo se utiliza. - Si una objeto sin
StaticResponse
teclas se pasa, se enviará como un cuerpo de respuesta JSON. Por ejemplo, pasando{ foo: 'bar' }
es equivalente a pasar{ body: { foo: 'bar' } }
. - Si un llamar de vuelta se pasa, se llamará siempre que se reciba una solicitud que coincida con esta ruta, siendo el primer parámetro el objeto de solicitud. Desde dentro de la devolución de llamada, puede modificar la solicitud saliente, enviar una respuesta, acceder a la respuesta real y mucho más. Consulte “Solicitudes interceptadas” para obtener más información.
Rendimientos
-
cy.intercept()
rendimientosnull
. -
cy.intercept()
se puede crear un alias, pero de lo contrario no se puede encadenar más. - Esperando un alias
cy.intercept()
La ruta que usa cy.wait () producirá un objeto que contiene información sobre el ciclo de solicitud / respuesta coincidente. Consulte Uso del objeto cedido para ver ejemplos de cómo utilizar este objeto.
Ejemplos de
URL coincidente
Puede proporcionar la URL completa para que coincida
// will match any request that exactly matches the URL // matches GET https://prod.cypress.io/users // won't match GET https://staging.cypress.io/users cy.intercept('https://prod.cypress.io/users')
Puede proporcionar un minimatch
patrón
// will match any HTTP method to urls that end with 3 or 5 cy.intercept('**/users?_limit=+(3|5)')
Propina: puede evaluar su URL usando la consola de DevTools para ver si el minimatch
patrón es correcto.
// paste into the DevTools console while Cypress is running Cypress.minimatch( 'https://jsonplaceholder.cypress.io/users?_limit=3', '**/users?_limit=+(3|5)' ) // true // print verbose debug information Cypress.minimatch( 'https://jsonplaceholder.cypress.io/users?_limit=3', '**/users?_limit=+(3|5)', { debug: true } ) // true + lots of debug messages
Incluso puede agregar una afirmación a la prueba para asegurarse de que la URL coincida
// arguments are url and the pattern expect( Cypress.minimatch( 'https://jsonplaceholder.cypress.io/users?_limit=3', '**/users?_limit=+(3|5)' ), 'Minimatch test' ).to.be.true
Para la coincidencia más potente, proporcione una expresión regular
cy.intercept(//users?_limit=(3|5)$/).as('users') cy.get('#load-users').click() cy.wait('@users').its('response.body').should('have.length', 3) // intercepts _limit=5 requests cy.get('#load-five-users').click() cy.wait('@users').its('response.body').should('have.length', 5)
Esperando una solicitud
Utilice cy.wait () con cy.intercept()
alias para esperar a que se complete el ciclo de solicitud / respuesta.
Con URL
cy.intercept('http://example.com/settings').as('getSettings') // once a request to http://example.com/settings responds, this 'cy.wait' will resolve cy.wait('@getSettings')
Con RouteMatcher
cy.intercept({ url: 'http://example.com/search*', query: { q: 'expected terms' }, }).as('search') // once any type of request to http://example.com/search with a querystring containing // 'q=expected+terms' responds, this 'cy.wait' will resolve cy.wait('@search')
Usando el objeto cedido
Usando cy.wait () en un cy.intercept()
El alias de ruta produce un objeto de intercepción que representa el ciclo de solicitud / respuesta:
cy.wait('@someRoute').then((interception) => { // 'interception' is an object with properties 'id', "https://foroayuda.es/cypress/api/commands/request" and 'response' })
Puedes encadenar .its()
y .should()
para hacer valer contra los ciclos de solicitud / respuesta:
// assert that a request to this route was made with a body that included 'user' cy.wait('@someRoute').its('request.body').should('include', 'user') // assert that a request to this route received a response with HTTP status 500 cy.wait('@someRoute').its('response.statusCode').should('eq', 500) // assert that a request to this route received a response body that includes 'id' cy.wait('@someRoute').its('response.body').should('include', 'id')
Aliasing de solicitudes individuales
Los alias se pueden establecer por solicitud configurando el alias
propiedad de la solicitud interceptada:
cy.intercept('POST', '/graphql', (req) => { if (req.body.hasOwnProperty('query') && req.body.query.includes('mutation')) { req.alias = 'gqlMutation' } }) // assert that a matching request has been made cy.wait('@gqlMutation')
Aliasing de solicitudes GraphQL individuales
Los alias se pueden establecer por solicitud configurando el alias
propiedad de la solicitud interceptada.
Esto es útil contra los puntos finales GraphQL para esperar consultas y mutaciones específicas.
Dado que el operationName
La propiedad es opcional en las solicitudes GraphQL, podemos alias
con o sin esta propiedad.
Con operationName
propiedad:
cy.intercept('POST', '/graphql', (req) => { if (req.body.operationName.includes('ListPosts')) { req.alias = 'gqlListPostsQuery' } }) // assert that a matching request for the ListPosts Query has been made cy.wait('@gqlListPostsQuery')
cy.intercept('POST', '/graphql', (req) => { if (req.body.operationName.includes('CreatePost')) { req.alias = 'gqlCreatePostMutation' } }) // assert that a matching request for the CreatePost Mutation has been made cy.wait('@gqlCreatePostMutation')
Sin operationName
propiedad:
cy.intercept('POST', '/graphql', (req) => { const { body } = req if (body.hasOwnProperty('query') && body.query.includes('ListPosts')) { req.alias = 'gqlListPostsQuery' } }) // assert that a matching request for the ListPosts Query has been made cy.wait('@gqlListPostsQuery')
cy.intercept('POST', '/graphql', (req) => { const { body } = req if (body.hasOwnProperty('query') && body.query.includes('CreatePost')) { req.alias = 'gqlCreatePostMutation' } }) // assert that a matching request for the CreatePost Mutation has been made cy.wait('@gqlCreatePostMutation')
Esperando errores
Puede usar cy.wait () para esperar solicitudes que terminan con errores de red:
cy.intercept('GET', '/should-err', { forceNetworkError: true }).as('err') // assert that this request happened, and that it ended in an error cy.wait('@err').should('have.property', 'error')
Apuntando una respuesta
Con una cuerda
// requests to '/update' will be fulfilled with a body of "success" cy.intercept('/update', 'success')
Con un accesorio
// requests to '/users.json' will be fulfilled // with the contents of the "users.json" fixture cy.intercept('/users.json', { fixture: 'users.json' })
Con un StaticResponse
objeto
A StaticResponse
El objeto representa una respuesta a una solicitud HTTP y se puede utilizar para stub de rutas:
const staticResponse = { /* some StaticResponse properties here... */ } cy.intercept('/projects', staticResponse)
Por ejemplo, para apuntar una respuesta con un cuerpo JSON:
cy.intercept('/projects', { body: [{ projectId: '1' }, { projectId: '2' }], })
O para los encabezados de código auxiliar, el código de estado y el cuerpo de una sola vez:
cy.intercept('/not-found', { statusCode: 404, body: '404 Not Found!', headers: { 'x-not-found': 'true', }, })
Ver “StaticResponse
objetos “para obtener más información sobre StaticResponse
s.
Interceptar una solicitud
Afirmar en una solicitud
cy.intercept('POST', '/organization', (req) => { expect(req.body).to.include('Acme Company') })
Modificar una solicitud saliente
Puede utilizar la devolución de llamada del controlador de solicitudes para modificar la solicitud antes de que se envíe.
cy.intercept('POST', '/login', (req) => { // set the request body to something different before it's sent to the destination req.body = 'username=janelane&password=secret123' })
Agregar un encabezado a una solicitud saliente
Puede agregar un encabezado a una solicitud saliente o modificar un encabezado existente
cy.intercept('/req-headers', (req) => { req.headers['x-custom-headers'] = 'added by cy.intercept' })
Nota: el nuevo encabezado NO se mostrará en la pestaña Red del navegador, ya que la solicitud ya salió del navegador. Aún puede confirmar que se agregó el encabezado esperando en la intercepción como se muestra a continuación:
cy.intercept('/req-headers', (req) => { req.headers['x-custom-headers'] = 'added by cy.intercept' }).as('headers') // the application makes the call ... // confirm the custom header was added cy.wait('@headers') .its('request.headers') .should('have.property', 'x-custom-headers', 'added by cy.intercept')
Agregar, modificar o eliminar un encabezado a todas las solicitudes salientes
Puede agregar, modificar o eliminar un encabezado a todas las solicitudes salientes usando un beforeEach()
en el cypress/support/index.js
expediente
// Code from Real World App (RWA) // cypress/support/index.ts import './commands' beforeEach(() => { cy.intercept( { url: 'http://localhost:3001/**', middleware: true }, // Delete 'if-none-match' header from all outgoing requests (req) => delete req.headers['if-none-match'] ) })
Ejemplo del mundo real
Clonar el Aplicación del mundo real (RWA) y consulte el cypress / support / index.ts archivo para un ejemplo de trabajo.
Apuntando dinámicamente una respuesta
Puedes usar el req.reply()
función para controlar dinámicamente la respuesta a una solicitud.
cy.intercept('/billing', (req) => { // functions on 'req' can be used to dynamically respond to a request here // send the request to the destination server req.reply() // respond to the request with a JSON object req.reply({ plan: 'starter' }) // send the request to the destination server, and intercept the response req.continue((res) => { // 'res' represents the real destination's response // See "Intercepting a response" for more details and examples }) })
Consulte “Solicitudes interceptadas” para obtener más información sobre req
objeto y sus propiedades y métodos.
Devolver una promesa
Si se devuelve una promesa de la devolución de llamada de ruta, se esperará antes de continuar con la solicitud.
cy.intercept('POST', '/login', (req) => { // you could asynchronously fetch test data... return getLoginCredentials().then((credentials) => { // ...and then, use it to supplement the outgoing request req.headers['authorization'] = credentials }) })
Pasar una solicitud al siguiente controlador de solicitudes
Si req.reply()
o req.continue()
no se llama explícitamente dentro de un controlador de solicitudes, las solicitudes pasarán al siguiente controlador de solicitudes hasta que no quede ninguna.
// you could have a top-level middleware handler that sets an auth token on all requests // setting `middleware: true` will cause this to always be called first cy.intercept('http://api.company.com/', { middleware: true }, (req) => { req.headers['authorization'] = `token ${token}` }) // and then have another handler that more narrowly asserts on certain requests cy.intercept('POST', 'http://api.company.com/widgets', (req) => { expect(req.body).to.include('analytics') }) // a POST request to http://api.company.com/widgets would hit both // of those callbacks, middleware first, then the request would be sent out // with the modified request headers to the real destination
Interceptar una respuesta
Dentro de una devolución de llamada pasada a req.continue()
, puede acceder a la respuesta real del servidor de destino.
cy.intercept('/integrations', (req) => { // req.continue() with a callback will send the request to the destination server req.continue((res) => { // 'res' represents the real destination response // you can manipulate 'res' before it's sent to the browser }) })
Consulte “Respuestas interceptadas” para obtener más información sobre el res
objeto. Consulte “Control de la solicitud de salida con req.continue()
“para obtener más información sobre req.continue()
.
Afirmar en una respuesta
cy.intercept('/projects/2', (req) => { req.continue((res) => { expect(res.body).to.include('My Project') }) })
Devolver una promesa
Si se devuelve una Promesa de la devolución de llamada de ruta, se esperará antes de enviar la respuesta al navegador.
cy.intercept('/users', (req) => { req.continue((res) => { // the response will not be sent to the browser until 'waitForSomething()' resolves return waitForSomething() }) })
Acelerar o retrasar la respuesta a todas las respuestas entrantes
Puede acelerar o retrasar todas las respuestas entrantes mediante un beforeEach()
en el cypress/support/index.js
expediente
// Code from Real World App (RWA) // cypress/support/index.ts import { isMobile } from './utils' import './commands' // Throttle API responses for mobile testing to simulate real world conditions if (isMobile()) { cy.intercept({ url: 'http://localhost:3001/**', middleware: true }, (req) => { req.on('response', (res) => { // Throttle the response to 1 Mbps to simulate a mobile 3G connection res.setThrottle(1000) }) }) }
Ejemplo del mundo real
Clonar el Aplicación del mundo real (RWA) y consulte el cypress / support / index.ts archivo para un ejemplo de trabajo.
Solicitudes interceptadas
Si se pasa una función como controlador de una cy.intercept()
, se llamará con el primer argumento como un objeto que representa la solicitud HTTP interceptada:
cy.intercept('/api', (req) => { // `req` represents the intercepted HTTP request })
Desde aquí, puede hacer varias cosas con la solicitud interceptada:
- puede modificar y afirmar las propiedades de la solicitud (cuerpo, encabezados, URL, método …)
- la solicitud se puede enviar al servidor ascendente real
- opcionalmente, puede interceptar la respuesta de este
- se puede proporcionar una respuesta para eliminar la solicitud
- los oyentes se pueden adjuntar a varios eventos en la solicitud
Solicitar propiedades de objeto
El objeto de solicitud (req
) tiene varias propiedades de la propia solicitud HTTP. Todas las siguientes propiedades en req
se puede modificar excepto para httpVersion
:
{ /** * The body of the request. * If a JSON Content-Type was used and the body was valid JSON, this will be an object. * If the body was binary content, this will be a buffer. */ body: string | object | any /** * The headers of the request. */ headers: { [key: string]: string } /** * Request HTTP method (GET, POST, ...). */ method: string /** * Request URL. */ url: string /** * The HTTP version used in the request. Read only. */ httpVersion: string }
req
también tiene algunas propiedades opcionales que se pueden configurar para controlar el comportamiento específico de Cypress:
{ /** * If provided, the number of milliseconds before an upstream response to this request * will time out and cause an error. By default, `responseTimeout` from config is used. */ responseTimeout?: number /** * Set if redirects should be followed when this request is made. By default, requests will * not follow redirects before yielding the response (the 3xx redirect is yielded) */ followRedirect?: boolean /** * If set, `cy.wait` can be used to await the request/response cycle to complete for this * request via `cy.wait('@alias')`. */ alias?: string }
Cualquier modificación a las propiedades de req
se conservará en otros controladores de solicitudes y, finalmente, se fusionará con la solicitud HTTP saliente real.
Controlando la solicitud saliente con req.continue()
Vocación req.continue()
sin ningún argumento hará que la solicitud se envíe saliente, y la respuesta se devolverá al navegador después de que se haya llamado a otros oyentes. Por ejemplo, el siguiente código modifica un POST
solicitud y luego la envía al servidor ascendente:
cy.intercept('POST', '/submitStory', (req) => { req.body.storyName = 'some name' // send the modified request and skip any other matching request handlers req.continue() })
Si se pasa una función a req.continue()
, la solicitud se enviará al servidor ascendente real y se llamará a la devolución de llamada con la respuesta una vez que la respuesta se haya recibido completamente del servidor. Ver “Respuestas interceptadas”
Nota: llamando req.continue()
evitará que la solicitud se propague al siguiente controlador de solicitudes coincidente en línea. Consulte “Ciclo de vida de la interceptación” para obtener más información.
Proporcionar una respuesta de código auxiliar con req.reply()
los req.reply()
La función se puede utilizar para enviar una respuesta de código auxiliar para una solicitud interceptada. Pasando una cadena, objeto o StaticResponse
para req.reply()
, la solicitud puede impedir que llegue al servidor de destino.
Por ejemplo, el siguiente código elimina una respuesta JSON de un interceptor de solicitudes:
cy.intercept('/billing', (req) => { // dynamically get billing plan name at request-time const planName = getPlanName() // this object will automatically be JSON.stringified and sent as the response req.reply({ plan: planName }) })
En lugar de pasar un objeto simple o una cadena a req.reply()
, también puede pasar un StaticResponse
objeto. Con un StaticResponse
, puede forzar un error de red, retrasar / acelerar la respuesta, enviar un dispositivo y más.
Por ejemplo, el siguiente código sirve para un dispositivo elegido dinámicamente con un retraso de 500 ms:
cy.intercept('/api/users/*', async (req) => { // asynchronously retrieve fixture filename at request-time const fixtureFilename = await getFixtureFilenameForUrl(req.url) req.reply({ fixture: fixtureFilename, delay: 500, }) })
Ver el StaticResponse
documentación para obtener más información sobre las respuestas de stubbing de esta manera.
req.reply()
también admite taquigrafía, similar a res.send()
, para evitar tener que especificar un StaticResponse
objeto:
req.reply(body) // equivalent to `req.reply({ body })` req.reply(body, headers) // equivalent to `req.reply({ body, headers })` req.reply(statusCode, body, headers) // equivalent to `req.reply({ statusCode, body, headers})`
También hay dos funciones de conveniencia disponibles en req
:
{ /** * Destroy the request and respond with a network error. */ destroy(): void /** * Respond to this request with a redirect to a new 'location'. * @param statusCode HTTP status code to redirect with. Default: 302 */ redirect(location: string, statusCode?: number): void }
Nota: llamando req.reply()
finalizará la fase de solicitud y detendrá la solicitud de propagándose al siguiente controlador de solicitud coincidente en línea. Consulte “Ciclo de vida de la interceptación” para obtener más información.
Solicitar eventos
Para uso avanzado, varios eventos están disponibles en req
, que representan diferentes etapas del ciclo de vida de la interceptación.
Llamando req.on
, puedes suscribirte a diferentes eventos:
cy.intercept('/shop', (req) => { req.on('before:response', (res) => { /** * Emitted before `response` and before any `req.continue` handlers. * Modifications to `res` will be applied to the incoming response. * If a promise is returned, it will be awaited before processing other event handlers. */ }) req.on('response', (res) => { /** * Emitted after `before:response` and after any `req.continue` handlers - before the response is sent to the browser. * Modifications to `res` will be applied to the incoming response. * If a promise is returned, it will be awaited before processing other event handlers. */ }) req.on('after:response', (res) => { /** * Emitted once the response to a request has finished sending to the browser. * Modifications to `res` have no impact. * If a promise is returned, it will be awaited before processing other event handlers. */ }) })
Consulte “Respuestas interceptadas” para obtener más detalles sobre el res
objeto cedido por before:response
y response
. Consulte “Ciclo de vida de la interceptación” para obtener más detalles sobre cómo realizar pedidos.
Respuestas interceptadas
La respuesta se puede interceptar de dos formas:
- pasando una devolución de llamada a
req.continue()
dentro de un controlador de solicitudes - escuchando el
before:response
oresponse
solicitar eventos (ver “Solicitar eventos”)
El objeto de respuesta, res
, se pasará como primer argumento a la función del controlador:
cy.intercept('/url', (req) => { req.on('before:response', (res) => { // this will be called before any `req.continue` or `response` handlers }) req.continue((res) => { // this will be called after all `before:response` handlers and before any `response` handlers // by calling `req.continue`, we signal that this request handler will be the last one, and that // the request should be sent outgoing at this point. for that reason, there can only be one // `req.continue` handler per request. }) req.on('response', (res) => { // this will be called after all `before:response` handlers and after the `req.continue` handler // but before the response is sent to the browser }) })
Propiedades del objeto de respuesta
El objeto de respuesta (res
) cedido a los controladores de respuesta tiene varias propiedades de la propia respuesta HTTP. Todas las siguientes propiedades en res
se puede modificar:
{ /** * The body of the response. * If a JSON Content-Type was used and the body was valid JSON, this will be an object. * If the body was binary content, this will be a buffer. */ body: string | object | any /** * The headers of the response. */ headers: { [key: string]: string } /** * The HTTP status code of the response. */ statusCode: number /** * The HTTP status message. */ statusMessage: string }
res
también tiene algunas propiedades opcionales que se pueden configurar para controlar el comportamiento específico de Cypress:
{ /** * Kilobits per second to send 'body'. */ throttleKbps?: number /** * Milliseconds to delay before the response is sent. */ delay?: number }
Cualquier modificación a las propiedades de res
se conservará en otros controladores de respuesta y, finalmente, se fusionará con la respuesta HTTP entrante real.
Terminando la respuesta con res.send()
Para finalizar la fase de respuesta de la solicitud, llame res.send()
. Opcionalmente, puede pasar un StaticResponse
para res.send()
, que se fusionará con la respuesta real.
Cuando res.send()
se llama, la fase de respuesta finalizará inmediatamente y no se llamará a ningún otro controlador de respuesta para la solicitud actual. He aquí un ejemplo de cómo res.send()
puede ser usado:
cy.intercept('/notification', (req) => { req.continue((res) => { if (res.body.status === 'failed') { // sends a fixture body instead of the existing 'res.body' res.send({ fixture: 'success.json' }) } }) })
Ver el StaticResponse
documentación para obtener más información sobre el formato.
res.send()
también admite taquigrafía, similar a req.reply()
, para evitar tener que especificar un StaticResponse
objeto:
res.send(body) // equivalent to `res.send({ body })` res.send(body, headers) // equivalent to `res.send({ body, headers })` res.send(statusCode, body, headers) // equivalent to `res.send({ statusCode, body, headers})`
También hay dos funciones de conveniencia disponibles en res
:
{ /** * Wait for 'delay' milliseconds before sending the response to the client. */ setDelay: (delay: number) => IncomingHttpResponse /** * Serve the response at 'throttleKbps' kilobytes per second. */ setThrottle: (throttleKbps: number) => IncomingHttpResponse }
Nota: llamando res.send()
terminará la fase de respuesta y evitará que la respuesta se propague al siguiente controlador de respuesta coincidente en la línea. Consulte “Ciclo de vida de la interceptación” para obtener más información.
StaticResponse
objetos
A StaticResponse
representa una respuesta cortada a una solicitud HTTP. Puede suministrar un StaticResponse
a Cypress de 3 formas:
- Directamente a
cy.intercept()
, para apuntar una respuesta a una ruta:cy.intercept('/url', staticResponse)
- Para
req.reply()
, para apuntar una respuesta de un controlador de solicitudes:req.reply(staticResponse)
- Para
res.send()
, para apuntar una respuesta de un controlador de respuesta:res.send(staticResponse)
Las siguientes propiedades están disponibles en StaticResponse
. Todas las propiedades son opcionales:
{ /** * Serve a fixture as the response body. */ fixture?: string /** * Serve a static string/JSON object as the response body. */ body?: string | object | object[] /** * HTTP headers to accompany the response. * @default {} */ headers?: { [key: string]: string } /** * The HTTP status code to send. * @default 200 */ statusCode?: number /** * If 'forceNetworkError' is truthy, Cypress will destroy the browser connection * and send no response. Useful for simulating a server that is not reachable. * Must not be set in combination with other options. */ forceNetworkError?: boolean /** * Milliseconds to delay before the response is sent. */ delay?: number /** * Kilobits per second to send 'body'. */ throttleKbps?: number }
Consulte “Apuntar una respuesta con un StaticResponse
object “para ver ejemplos de stubbing con cy.intercept()
.
Ciclo de vida de la interceptación
El ciclo de vida de un cy.intercept()
la intercepción comienza cuando se envía una solicitud HTTP desde su aplicación que coincide con uno o más registrados cy.intercept()
rutas. A partir de ahí, cada intercepción tiene dos fases: solicitud y respuesta.
cy.intercept()
Las rutas coinciden en orden inverso a la definición, excepto para las rutas que se definen con { middleware: true }
, que siempre se ejecuta primero. Esto le permite anular los cy.intercept()
declaraciones definiendo una superposición cy.intercept()
.
Fase de solicitud
Los siguientes pasos se utilizan para manejar la fase de solicitud.
- Comience con la primera ruta coincidente de acuerdo con el algoritmo anterior (primero el middleware, seguido de los controladores en orden inverso).
- Era un manejador (cuerpo,
StaticResponse
, o función) suministrado acy.intercept()
? Si no es así, continúe con el paso 7. - Si el manejador era un cuerpo o
StaticResponse
, finalice inmediatamente la solicitud con esa respuesta. - Si el controlador era una función, llame a la función con
req
, la solicitud entrante, como primer argumento. Consulte “Solicitudes interceptadas” para obtener más información sobrereq
objeto.- Si
req.reply()
se llama, finalice inmediatamente la fase de solicitud con la respuesta proporcionada. Consulte “Proporcionar una respuesta de código auxiliar conreq.reply()
“. - Si
req.continue()
se llama, finaliza inmediatamente la fase de solicitud y envía la solicitud al servidor de destino. Si se proporciona una devolución de llamada areq.continue()
, se llamará durante la fase de respuesta
- Si
- Si el manejador devolvió una Promesa, espere a que se resuelva.
- Fusionar cualquier modificación del objeto de solicitud con la solicitud real.
- Si hay otra coincidencia
cy.intercept()
, vuelva al paso 2 y continúe siguiendo los pasos con esa ruta. - Envíe la solicitud saliente al servidor de destino y finalice la fase de solicitud. La fase de respuesta comenzará una vez que se reciba una respuesta.
Fase de respuesta
Una vez que se recibe la respuesta HTTP del servidor ascendente, se aplican los siguientes pasos:
- Obtener una lista de registrados
before:response
oyentes de eventos. - Para cada
before:response
oyente (si lo hay), llámelo con elres
objeto.- Si
res.send()
se llama, finaliza la fase de respuesta y fusiona los argumentos pasados con la respuesta. - Si se devuelve una Promesa, espérela. Fusionar cualquier propiedad de respuesta modificada con la respuesta real.
- Si
- Si un
req.continue()
con devolución de llamada se declara para esta ruta, llame a la devolución de llamada con elres
objeto.- Si
res.send()
se llama, finaliza la fase de respuesta y fusiona los argumentos pasados con la respuesta. - Si se devuelve una Promesa, espérela. Fusionar cualquier propiedad de respuesta modificada con la respuesta real.
- Si
- Obtenga una lista de registrados
response
oyentes de eventos. - Para cada
response
oyente (si lo hay), llámelo con elres
objeto.- Si
res.send()
se llama, finaliza la fase de respuesta y fusiona los argumentos pasados con la respuesta. - Si se devuelve una Promesa, espérela. Fusionar cualquier propiedad de respuesta modificada con la respuesta real.
- Si
- Envíe la respuesta al navegador.
- Una vez que la respuesta esté completa, obtenga una lista de
after:response
oyentes de eventos. - Para cada
after:response
oyente (si lo hay), llámelo con elres
objeto (menosres.send
)- Si se devuelve una Promesa, espérela.
- Finaliza la fase de respuesta.
Historia
Versión | Cambios |
---|---|
7.0.0 | Remoto matchUrlAgainstPath opción de RouteMatcher , orden de controlador inverso, eventos de solicitud agregados, coincidencia de URL de subcadena eliminada, eliminado cy.route2 alias, agregado middleware Opción RouteMatcher, renombrada res.delay() para res.setDelay() y res.throttle() para res.setThrottle() . |
6.4.0 | Renombrado delayMs propiedad a delay (compatible con versiones anteriores). |
6.2.0 | Adicional matchUrlAgainstPath opción a RouteMatcher . |
6.0.0 | Renombrado cy.route2() para cy.intercept() . |
6.0.0 | Remoto experimentalNetworkStubbing y lo convirtió en el comportamiento predeterminado. |
5.1.0 | Experimental agregado cy.route2() comando bajo experimentalNetworkStubbing opción. |
Notas
cy.intercept()
no se puede depurar usando cy.request()
cy.request()
envía solicitudes a los puntos finales reales, omitiendo los definidos mediante cy.intercept()
La intencion de cy.request()
se utiliza para comprobar los puntos finales en un servidor real en ejecución sin tener que iniciar la aplicación de interfaz.
Ver también
.as()
cy.fixture()
cy.wait()
- Migrando
cy.route()
paracy.intercept()
-
cy.intercept()
recetas de ejemplo con ejemplos del mundo real- espiar solicitudes
- tachando cualquier solicitud
- cambiando la respuesta del servidor
- interceptar recursos estáticos como HTML y CSS
- redirigir solicitudes
- respondiendo con diferentes respuestas
- Cómo funciona cy.intercept presentación
-
Cypress Cy. Problemas de intercepción con avanzado
cy.intercept
consejos para resolver los problemas comunes:- La intercepción se registró demasiado tarde
-
cy.wait
usa la intersección - La respuesta fue almacenada en caché
- La solicitud coincidió con múltiples intercepciones
- Cómo sobrescribir interceptores
- Cómo evitar el uso de comandos de Cypress dentro del interceptor
- Envío de diferentes respuestas
-
cy.route()
vscy.route2()
entrada en el blog - Stubbing inteligente GraphQL en Cypress entrada en el blog
-
Problemas abiertos para
net stubbing
y problemas cerrados paranet stubbing