当前位置:网站首页>Cypress series (101) - intercept() command

Cypress series (101) - intercept() command

2020-12-07 15:40:41 itread01

If you want to learn from scratch Cypress, You can see the following series of articles

https://www.cnblogs.com/poloyy/category/1768839.html

 

effect

Use this command to manage at the network layer HTTP The act of asking

 

It includes the following functions

  • For any type of HTTP Request for stub or spy
  • stay HTTP Before the request is sent to the target server , You can modify HTTP Ask for body、headers、URL( Similar to the packet capture tool to interrupt the request and then modify )
  • To deal with dynamically or statically HTTP The response to the request is made stub
  • receive HTTP You can respond to  HTTP Respond to body、headers、status、code Make a change ( Similar to the package capture tool, it breaks the response and modifies it )
  • Full access to all... Is available at all stages HTTP Ask for

 

Compared with cy.route() Different

 cy.route()  Order to explain in detail :https://www.cnblogs.com/poloyy/p/13852941.html

  • Can block all types of network requests , Include Fetch API, Page load ,XMLHttpRequest, Resource loading, etc
  • There is no need to call before use  cy.server() , Actually  cy.server()  It doesn't affect at all  cy.intercept() 
  • By default, the request method is not set to GET

 

Grammar format

cy.intercept(url, routeHandler?)
cy.intercept(method, url, routeHandler?)
cy.intercept(routeMatcher, routeHandler?)

 

url

Requests to match URL , It can be a string or a regular expression

cy.intercept('http://example.com/widgets')
cy.intercept('http://example.com/widgets', { fixture: 'widgets.json' })

If there is no specified request method , Can match any type of request method

 

method

Request method

cy.intercept('POST', 'http://example.com/widgets', {
  statusCode: 200,
  body: 'it worked!'
})

 

routeMatcher 

  • It's an object
  • Used to match which incoming HTTP Ask for
  • All object properties are optional , Not required
  • All properties set must match the route to process the request
  • If you pass a string to any property , Will use minimatch Will match the request globally

It has the following properties

{
  /**
   *  And  HTTP Basic The user name and password used in authentication match 
   */
  auth?: { username: string | RegExp, password: string | RegExp }

  /**
   *  And on request  HTTP Headers  matching 
   */
  headers?: {
    [name: string]: string | RegExp
  }

  /**
   *  And on request  hostname  matching 
   */
  hostname?: string | RegExp

  /**
   * If 'true',  Only  https  's request will be matched 
   * If 'false',  Only  http  's request will be matched 
   */
  https?: boolean

  /**
   *  And on request  method  Request method matching 
   *  Presupposition  '*',  Match all types  method
   */
  method?: string | RegExp

  /**
   *  The path after the host name ,  It includes  ?  The following query arguments 
   * www.baidu.com/s?wd=2
   */
  path?: string | RegExp

  /**
   *  and  path  The same thing ,  But it doesn't matter  ?  The following query arguments 
   * www.baidu.com/s
   */
  pathname?: string | RegExp

  /**
   *  Matches the specified port ,  Or pass an array of multiple ports ,  One of the matches will do 
   */
  port?: number | number[]

  /**
   *  And the request path  ?  The following query arguments match 
   * wd=2
   */
  query?: {
    [key: string]: string | RegExp
  }

  /**
   *  Complete request  url
   * http://www.baidu.com/s?wd=2
   */
  url?: string | RegExp
}

   

routeHandler 

  • routeHandler Defines if the request and routeMatcher Match the specified processing that will be performed on the request
  • Acceptable data types :string、object、Function、StaticResponse

 

StaticResponse

  • It is equivalent to a custom response body object
  • Can be customized Response headers、HTTP Status code 、Response body etc.
  • The detailed chestnut will be explained later

 

StaticResponse Properties of the object

{
  /**
   *  Will  fixture  Archives as the response subject ,  With  cypress/fixtures  For root 
   */
  fixture?: string
  /**
   *  Put a string or  JSON  Object as response subject 
   */
  body?: string | object | object[]
  /**
   *  Respond to  headers
   * @default {}
   */
  headers?: { [key: string]: string }
  /**
   *  Response status code 
   * @default 200
   */
  statusCode?: number
  /**
   *  If  true, Cypress  It will destroy the Internet connection ,  And don't send any response 
   *  It is mainly used to simulate inaccessible servers 
   *  Do not use in combination with other options 
   */
  forceNetworkError?: boolean
  /**
   *  The number of milliseconds to delay before sending a response 
   */
  delayMs?: number
  /**
   *  How much  kbps  Transfer responders 
   */
  throttleKbps?: number
}

 

string

  • If you pass a string , This value corresponds to the response body Value
  • Equivalent to StaticResponse thing  { body: "foo" } 

 

object

  • If it's delivered, no StaticResponse The object of the key , Then it will act as JSON Respond to Body Transmit
  • for example , {foo:'bar'}  Equivalent to StaticResponse thing  {body:{foo:'bar'}} 

 

function

  • If you pass a callback function , When a request matches the route, the function will be called automatically
  • The first argument to the function is the request object
  • Inside the callback function , You can modify outgoing requests 、 Transmit response 、 Access the actual response
  • The detailed chestnut will be explained later

 

Command returns results

  • return null
  • You can connect to  as()  Alias , But you can't link other commands
  • have access to  cy.wait()  wait for  cy.intercept()  The route matches the request , This will produce an object , Contains the request on the match / Respond to relevant information

 

Pre preparation of actual chestnuts

Cypress Official project download address :https://github.com/cypress-io/cypress-example-kitchensink

 

Download and enter the project folder below

 

Start the project

npm start

 

Through URL Routing matches the chestnut of the request

Test code

 

Equivalent to route() Test code for

notes :  route()   The future will be abandoned

 

Execution results

The login request matches the route

 

Console Look at cy.wait() Objects returned

The most important thing, of course, is request and response Two properties

 

Through RouteMatcher Routing matches the chestnut of the request

Test code

Assertion request body and response status code

 

Execution results

 

Console  Look at cy.wait() Objects returned

 

Another way of asserting

//  Assert that a request matching this route received a request containing 【username】 Request for  body
cy.wait('@login3').its('request.body').should('have.property', 'username')

//  Assert that the request matching this route received  HTTP  Status code is  500
cy.wait('@login3').its('response.statusCode').should('eq', 200)

//  Assert that a request matching this route received a request containing 【redirect】 Request for  body
cy.wait('@login3').its('response.body').should('have.property', 'redirect')

But you can only write one at a time, not three at the same time , Therefore, it is recommended to be like code diagram , First  .then()  Make an assertion

 

Customize different types of response body of various chestnuts

Customize the response body of a pure string

Test code

 

Execution results

 

Interface response

 

Customize a JSON The response body of

Test code

From cypress Installation directory /fixtures  Read the corresponding data file , It becomes a response body Information about

 

test.json Data files

 

Execution results

 

Interface response

 

Customize a  StaticResponse The response body of

Test code

Customized response body、statusCode, And the delay time for the return response

 

Execution results

The delay is in effect

 

body and statusCode It's a custom profile

 

Block the requested chestnuts

Front operation

beforeEach(() => {
    cy.visit('http://localhost:7079/login')
})

 

Claim the chestnuts of the request

Test code

 

Execution results

 

Console View print results

You can see that the callback function has only one argument , Namely request Arguments

 

Emphasis

Cannot contain in callback function  cy.**()  The order of , If included, an error will be reported

In short, it's

 cy.type()  After the command is executed, it will return a promise thing , It also calls the callback function , The callback function calls again  cy.get()  Back to a promise thing ,Cypress Treat this as a test failure

 

Pass the request to the next routing handler

Preface

This means that a request can match multiple routes at the same time

 

Test code

 

Execution results

One login request matched two routes successfully , And the callback functions are executed in the matching order

 

Summary

The argument to the callback function is a request object , It can actually call the following methods

{
  /**
   *  Destroy the request and return a response to a network error 
   */
  destroy(): void

  /**
   *  Control the response to the request 
   *  If you pass in a function ,  Then it is a callback function ,  When responding, it calls 
   *  If the input is a  StaticResponse  thing ,  No requests will be made ,  Instead, the object is returned directly as a response 
   */
  reply(interceptor?: StaticResponse | HttpResponseInterceptor): void

  /**
   *  Use  response body( Required )  and  response header( Optional )  Respond to requests 
   */
  reply(body: string | object, headers?: { [key: string]: string }): void

  /**
   *  Use  HTTP  Status code ( Required )、 response body( Optional )、response header( Optional )  Respond to requests 
   */
  reply(status: number, body?: string | object, headers?: { [key: string]: string }): void

  /**
   *  Redirect to new  location  To respond to requests ,
   * @param statusCode  For redirection  HTTP  State code , Default: 302
   */
  redirect(location: string, statusCode?: number): void
}

 

Intercept the response chestnut

req.reply() Function details

Preface

have access to  req.reply()  Function to dynamically control the response to requests

 

Use explanation

cy.intercept('/login', (req) => {
    // functions on 'req' can be used to dynamically respond to a request here

    //  Send the request to the target server 
    req.reply()

    //  Put this  JSON  The object responds to the request 
    req.reply({plan: 'starter'})

    //  Send the request to the target server ,  And intercept the actual response returned by the server ,  And then follow up ( Similar to the packet capture tool response break point )
    req.reply((res) => {
        // res  It's the actual response object 
    })
})

 

.reply() Modify the response directly

Test code

 

Interface response content

 

Intercept the response of the chestnut

Test code

 

Execution results

 

Console View print results

One is request thing , One is response thing

 

Custom response content

Preface

  • have access to  resp.send()  Functions dynamically control the incoming response
  • in addition , When the response is sent to the browser , Yes resp Any modification of the will be retained
  • If you haven't called  resp.send() , Then it will be in  req.reply()  Implicit call after callback function is completed

 

Use explanation

cy.intercept('/notification', (req) => {
    req.reply((resp) => {
        // Success  Will act as  response body  Back to the browser 
        resp.send('Success')

        //  Will  success.json  The information in it serves as  response body  Back to the browser 
        resp.send({fixture: 'success.json'})

        //  Delay the response  1000ms
        resp.delay(1000)

        //  Limit the response to  64kbps
        resp.throttle(64)
    })
})

 

Passing strings as response content

Test code

 

Interface response content

 

Transmission JSON Object as response content

Test code

 

Interface response content

 

Transmission StaticResponse Object as response content

Test code

 

Interface response content

 

resp Summary of callable functions

{
/**
*  Can be customized  response statusCode、response body、response header
*  You can also send it directly  StaticResponse  thing 
*/
send(status: number, body?: string | number | object, headers?: { [key: string]: string }): void
send(body: string | object, headers?: { [key: string]: string }): void
send(staticResponse: StaticResponse): void
/**
*  Continue to return the response 
*/
send(): void
/**
*  wait for  delayMs  millisecond , Then the response is sent to the client 
*/
delay: (delayMs: number) => IncomingHttpResponse
/**
*  How much  kbps  Speed transfer response 
*/
throttle: (throttleKbps: number) => IncomingHttpResponse
}

 

版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://chowdera.com/2020/12/20201207154008810i.html