Git Product home page Git Product logo

cypress-plugin-api's Introduction

Cypress plugin API

Cypress plugin for effective API testing. Imagine Postman, but in Cypress. Prints out information about the API call in the Cypress App UI.

Cypress plugin for testing API

Features

Installation

Install this package:

npm i cypress-plugin-api
# or
yarn add cypress-plugin-api

Import the plugin into your cypress/support/e2e.js file:

import 'cypress-plugin-api'
// or
require('cypress-plugin-api')

Usage

You can now use cy.api() command. This command works exactly like cy.request() but in addition to calling your API, it will print our information about the API call in your Cypress runner.

Snapshot only mode

If you want to combine your API calls with your UI test, you can now use snapshotOnly mode, that will hide the plugin UI view after command ends. You can access it within the timeline.

snapshotOnly mode is set to false by default. To set up snapshotOnly mode, add following to your test configuration:

it('my UI & API test', { env: { snapshotOnly: true } }, () => {

  cy.visit('/') // open app
  cy.api('/item') // call api
  cy.get('#myElement') // still able to access element on page

})

or you can add the configuration to your cypress.config.{js,ts} file:

import { defineConfig } from 'cypress'

export default defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
    },
    env: {
      snapshotOnly: true
    }
  },
})

Hiding credentials

You can hide your credentials by passing hideCredentials option to your env configuration. This will hide all the credentials from UI, but you can still access them via console. This option is set to false by default.

it('my secret test', { env: { hideCredentials: true } }, () => {

  cy.api({
      url: '/',
      headers: {
        authorization: Cypress.env('myToken')
      }
    })

})

The result will look like this:

Cypress plugin for testing API

You can also hide any credentials you want by defining array of keys in hideCredentialsOptions,

it('my secret test', { 
  env: { 
    hideCredentials: true, 
    hideCredentialsOptions: {
      headers: ['authorization'],
      auth: ['pass'],
      body: ['username'],
      query: ['password']
    }
  }
}, () => {

  cy.api({
      url: '/',
      headers: {
        authorization: Cypress.env('myToken') // hidden
      },
      auth: {
        pass: Cypress.env('myPass') // hidden
      },
      body: {
        username: Cypress.env('myUser') // hidden
      },
      qs: {
        password: Cypress.env('password') // hidden
      }
    })

})

This will override all the defaults set by hideCredentials.

requestMode - enable UI for cy.request() command

This setting adds all the functionality of cy.api() command to cy.request(). It’s set to false by default. This means that when you call cy.request() in your test, it will show UI.

TypeScript support

In most cases, types work just by installing plugin, but you can add the types to your tsconfig.json

{
  "types": ["cypress-plugin-api"]
}

This will add types for cy.api() command, it’s returned values as well as env properties.

Issues

All the issues can be found on issues page, feel free to open any new ones or contribute with your own code.


...powered by coffee and love ❤️ Filip Hric

cypress-plugin-api's People

Contributors

dodosaurus avatar filiphric avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cypress-plugin-api's Issues

UI does not show when cy.session() is part of the test

when cy.session() is called it navigates to a blank page and shows a custom blank page in Cypress UI. This however removes the plugin completely.

Somehow I need to tap in to the Cypress event that navigates to the about:blank page and tell it to not remove the code that I’m adding in the Cypress runner. I’ll create a separate issue for this.

Connected to #4

Display the clicked step on the right pane

When we are running the test, we always have the UI scroll the the latest API call, which is great.

Once the test is over, if we click on a step, it does not get focused on in the UI; we have to scroll all the way to the bottom to see the matching call.

It would be great if we clicked on the step and saw the relevant UI step without having to scroll.

Repro:

git clone https://github.com/muratkeremozcan/cypress-crud-api-test.git
cd cypress-crud-api-test
yarn cy:open

Run any test (I ran the spok test).
Click on one of the middle steps; we do not get the matching UI on the right pane, we have to scroll to the bottom.

Untitled_.Nov.18.2022.1_59.PM.mp4

[Request] Scrolling to Payload

Hi Filip! Is it possible the scrolling to related request/response body payload which is right panel, when the clicking to the request endpoint in command log? Thanks.

baseUrl is appended to the actual API URL

Hi Filip,

There is a bug in v2.2.1 that url input shows the baseUrl.

Reproduce steps:
Create a test like:

it("baseUrl should not be shown", () => {
  cy.api("https://http.cat/100");
});

Check the url shown on the page in Cypress.
image
You can see that http://localhost:3003 is the baseUrl that should not be shown.

Support for passing parameters instead of object

It's mentioned on the README page that cy.api() works exactly as cy.request(), but that is not 100% true. You can use cy.request() like this:

cy.request('POST', '/items', { name: 'item 1' })

Or you can pass 1 or 2 arguments and it will work according to docs.

It would be nice if cy.api() could handle these arguments.

size NaN undefined

Hi Filip,

  • in version 2.1.1 of cypress-plugin-api the Size field is returning NaN undefined
  • some blank margins are being displayed in the layout

image

Add ability to copy data from snapshots as well

Currently it is possible to copy data from API calls from last test only. This is because snapshots don’t allow full functionality. They’re just snapshots.

Possible solution: add a button to window.top that would copy data from an invisible element that would contain the raw data.

Might need some thinking around the fact that there may be multiple requests on the snapshot and multiple items to copy from.

Calls to cy.request after cy.api is called show up in the new UI view

Version: 2.6.0

Not sure if this is intentional or not, but felt like a bug. After you call cy.api for the first time, calls to cy.request also show up in the new UI to view api requests. It would be nice if only cy.api calls showed up in the UI.

beforeEach(() => {
    cy.request({
      log: false,
      method: 'POST',
      url: '/missions/reset',
      headers: {
        Authorization: 'resetcreds',
      },
    });
    cy.log('seeding db');
  });

  it('can delete mission', () => {
    cy.api('DELETE', '/missions/1').as('response');
    cy.get('@response').its('status').should('equal', 204);
  });

image

Ran into TypeError when cy.api() call was made from global hooks

Hi,

I'm having the following file structure

.
└── project/
    └── cypress/
        ├── e2e/
        │   └── *.cy.ts
        └── support/
            ├── e2e.js
            └── hooks.js

hooks.js contains global hooks. Example:

after('remove automation data', () => {
    removeAutomationData();
});

e2e.js contains

import './hooks';
import 'cypress-plugin-api';

When functions removeAutomationData() internally makes cy.api() request. I'm seeing the following error:

TypeError: Cannot read properties of undefined (reading 'Reproducing global hooks issue.should throw error for global hooks')
Because this error occurred during a `after all` hook we are skipping all of the remaining tests.
    at Context.eval (webpack:///./node_modules/cypress-plugin-api/dist/support.js:3:10683)

Screenshot 2022-11-18 at 7 56 54 AM

Note: If hooks are present directly inside *.cy.ts files then there is no issue in execution.

Optimize plugin performance

The plugin is doing very good in terms of performance, but here are some enhancement suggestions:

  • plugin mounts everytime cy.api() is called. this goes also for situations when cy.api() is called multiple times in single test. this does not come at a significant cost, but it is unnecessary smell (done by #26)
  • same goes for appending CSS styles. ideally just load it once for every test (done by #27)
  • clipboard button has some issues. especially for longer situation when a spec contains multiple tests, showing "copy to clipboard" button takes longer with every test for some reason. this might require some digging into how Vue renders things.

requestOnly mode

Mode that would allow you to just use cy.request() instead of cy.api()

rethink how credentials are hidden

the current way of setting up credentials to hide is not ideal. some issues:

  1. credentials are anonymized character by character, revealing the length of hidden attribute
  2. no ability to hide response attributes
  3. once the credential is hidden, there’s really no way of showing it anymore

I’m thinking that hiding credentials could instead be implemented by pure css. hide the credential we want to hide and reveal it on hover. don’t have the technical solution, but might make for a little nicer user experience

add ability to read queries from url

currently, request queries tab appears only when there is a qs parameter sent via cy.api(). but sometimes query is sent right from URL. it would be nice to have that overview available in these cases as well

When you use ` followRedirect: false` on a request, the plugin doesn't give you the request information properly.

Hey @filiphric! first of all, great work with this incredible plugin :)

We have a few tests to try the redirection on our website. Something like:

it(`[should be redirected from ${originUrl} with query params`, () => {
      cy.request({
        method: 'GET',
        url: originUrl,
        followRedirect: false,
      }).then(response => {
        expect(response.status).eq(301);
        expect(response.redirectedToUrl).eq(destinyUrl);
      });
    });

When we use cy.request() it works properly but when we updated the code and used your plugin, we got the following error:

image

It works properly with other cy.request but those tests are the only ones with the property followRedirect: false added on the request.

Could you please have a look? Let me know if there's anything else we could help you with :)

Again, great work!

feat: expose api function

I was just working on implementing this but I needed a way to wrap the cy.api(). It would be great if I could easily do something like this in my support file:

import { api } from 'cypress-plugin-api'

declare global {
  namespace Cypress {
    interface Chainable {
      api: typeof api
    }
  }
}

Cypress.Commands.add('api', myCustomMount)

timeout inside cy.request don't work

Hi, when I try to use the cy.request() timeout I get the following:

cy.request({
        method: 'GET',
        timeout: 30000,  // 30s
        url: Cypress.env('BASE_API_URL') + endpoint,
        headers: {
            authorization: authorization,
        },
        failOnStatusCode: false
});

Wait only 4 seconds

image

Could you please take a look at it? Thanks!

{ forceNetworkError: true } being presented in the url context

I have a doubt if this is a problem or not.

✅ This scenario returned status code 500 as expected. The lib concatenated the URL + { force network error: true }.
image

❌ This scenario returned status code 404 (expected 500). The lib concatenated the URL + { force network error: true }.
image

PS: The difference between the two requests is that one passes at the end of the url ${posIdCnpjNull} and the other /customers with the name of the endpoint (/customers).


Version:
"cypress": "^11.2.0"
"cypress-plugin-api": "^2.6.1"

trigger to show/not show whole URL

Some projects use multiple URLs in their repo. It would be nice to have option to turn on/off displaying of full URL, not just an appendix like it is now (in URL box of the UI, see screenshot).

image

Does not work with v9

Oops. Sorry about that. The registration of the plugin does not work as it should, I’ll give this the highest priority.

CI/stealth mode

There's a whole UI rendered when running in browser, but there's probably no need for this in CI (you might like the error screenshot, but error message will probably give you more info).

It would probably be useful to choose not to render anything based on a flag that users can set up.

Please add support for log: false so that passwords are not displayed in clear text

When using cy.request there is a parameter log: false, with which the command (and thus the password) are no longer displayed in the Test Runner. If I replace cy.request with cy.api, log: false is ignored and the user can read the password in plain text.

Example:

    cy.request({
        method: "POST",
        url: getOrchestrationLayerPrefixUrlBasedOnBaseUrl() + urls.LOGIN,
        body: {
            username: Cypress.env("AUTOMATED_TESTS_USERNAME1"),
            password: Cypress.env("AUTOMATED_TESTS_PASSWORD1"),
        },
        log: false,
    })

cyRequestLogFalse

    cy.api{
        method: "POST",
        url: getOrchestrationLayerPrefixUrlBasedOnBaseUrl() + urls.LOGIN,
        body: {
            username: Cypress.env("AUTOMATED_TESTS_USERNAME1"),
            password: Cypress.env("AUTOMATED_TESTS_PASSWORD1"),
        },
        log: false,
    })

cyApiLogFalse

v2

I’ve been working on version 2 of this plugin and I would love to hear some feedback on this. I plan to do couple of big changes that would overall keep the spirit of the plugin, but will change how it will be used.

The changes include tabs:

tabs.mov

When exploring snapshots, tabs are available by using snapshot for every state:

snapshot.mov

This is just a POC, I’ll definitely want to work on UI, especially dividing request and response.

I’m thinking of dividing request and responses, kinda like the layout of thunder client in vs code, which follows the same kind of pattern as many of the API testing tools:
Screenshot 2022-11-01 at 11 42 42

Of course, this layout should be responsive, so that in smaller viewports it will show response and request one below other, not side to side.

So a couple of questions on this:

  • do you like it?
  • would you like to see separate sections for request vs. response?
  • how crucial is it to unify snapshot experience with the experience of last test?
  • would you miss the "copy to clipboard" button if I got rid of it?
  • would you like to see "tests" tab, that would show assertion results? (I’m pretty sure it could be done, but need to confirm
  • would you want to trigger test from UI?
  • any export functions you would like to see?
  • would you like to have support for light/dark theme?

I’d be very happy to hear the feedback!

Also, feel like this is a good opportunity to mention my sponsors link ❤️

Using api() command in before hook does not work

If I include api() command to before all hook, cypress returns an error: cy.api is not a function Because this error occurred during a before all hook we are skipping the remaining tests in the current suite. For the request() command it works fine. Also, I did not get this error in before each hook.
Request example:

describe('send request', () => {
    before(() => {
         cy.api({
             method: 'GET',
             url: 'some/url',
                 auth: {
                     bearer: 'Login Token'
                 }
             }).then(response => {
                 expect(response.status, 'Response is not an error').to.eq(200);
                 }
            })
        })
    })

    it('should do something', () => {
        //tests
    })
})

plugin removes styles from visited page

during last big refactor, I’ve made a change that would remove added styles if plugin was in snapshotOnly mode. this needs fixing as we can get into situations when we don’t remove the correct style.

Hide token in response after request

We are currently able to hide certain parameters from the header, but when making a request to fetch a token, the token ends up being displayed in the request response, making it meaningless to hide the header since the sensitive data is still visible

image

Exemple to hide this response:
image

bug: Error when running the tests inside a foreach

Hi Filip, when running more than one test within foreach, the timeout error occurs

I'm using cypress version 12.1.0 and cypress-plugin-api version 2.6.1

//It does not work
const ceps = ['30350577', '01001000']
//it works
//const ceps = ['30350577']

describe('GET CEP', () => {
    ceps.forEach(cep => {
        it('search cep', () => {
            cy.api(`https://viacep.com.br/ws/${cep}/json/`).then((req) => {
                expect(req.status).to.eq(200)
            })
        })
    })
})

image

add ability to set default headers

it might be quite useful to set default headers so that whenever this plugin is used for robust api testing, users can set their own global headers

Stretch viewport

We don’t really need the viewport to be restricted to Cypress settings. In fact, having the full height and width available might be a good thing. Currently, Cypress dynamically changes scale of UI window, which could be disabled, but then it would be useful to find a way of keeping the scaling whilst having a full view.

Also, some people may not like this, so a toggle might be a good idea

hideCredentials: true is not working.

hideCredentials: true is not working.
Version - 2.3.1
OS: Windows 11
Browser: chrome.
Snapshot is attached for reference.
image

image
Clear Username and Password showing on UI, Snapshot attached for reference.
image

bug v2.5.0 - Timeout find element

Hi Filip!
I'm using cypress-plugin-api in version 2.5.0, in my e2 tests and when I make a call to the API it's returning the error below

image

example code
image

Make plugin responsive

UI does not look too good when on smaller viewports, it definitely might be worth to make it responsive and arrange panels vertically when on narrow viewport

TypeError Cannot read properties of undefined (reading 'toString') in node_modules/cypress-plugin-api/dist/support.js:11:828

This is a wonderful plugin but I am experiencing an issue and I am not 100% sure how to report it. I thought starting a conversation here would be a good way to start. I apologize if this is the wrong way to inform you of a possible issue as well.

The following is the output from the cypress runner. I realize it's obnoxiously long but I wanted you to have everything incase it's helpful. I am running cypress 9.7.0 (yes, I know it's old - I am waiting to upgrade for various reasons). I added the import 'cypress-plugin-api' statement to cypress > support > index.js. I can't determine why the plugin is behaving this way for this specific test. It works for other tests so I not sure if it is something that I have done that is causing this issue or not.

Please let me know if I can be of any assistance. This is a great package and your work is much appreciated!

4 then function(){} TypeError Cannot read properties of undefined (reading 'toString') [node_modules/cypress-plugin-api/dist/support.js:11:828](https://tinappsb.qa.paylocity.com/__/#) 9 | ),w.hasAttribute("data-start")||w.setAttribute("data-start",String(m+1))}k.textContent=l,t.highlightElement(k)},function(l){w.setAttribute(i,v),k.textContent=l})}}),t.plugins.fileHighlight={highlight:function(w){for(var k=(w||document).querySelectorAll(h),o=0,a;a=k[o++];)t.highlightElement(a)}};var q=!1;t.fileHighlight=function(){q||(console.warn("Prism.fileHighlight is deprecated. Use Prism.plugins.fileHighlight.highlight instead."),q=!0),t.plugins.fileHighlight.highlight.apply(this,arguments)}}()})(ee);Prism.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}};Prism.languages.webmanifest=Prism.languages.json;const de=e=>{try{JSON.parse(e)}catch{return!1}return!0},j=(e,d="json")=>{const t=d==="json"?JSON.stringify(e,null,2):e;if(e){let p=ee.exports.highlight(t,ee.exports.languages[d],d).split(
10 | ).map((b,f)=>${(f+1).toString().padStart(4," ")} ${b}).join(

11 | );return de(t)&&(p=p.replaceAll('<span class="token punctuation">{</span>','<details class="contents" open><summary class="inline-block brace"><span class="token punctuation">{</span></summary>').replaceAll('<span class="token punctuation">[</span>','<details class="contents" open><summary class="inline-block bracket"><span class="token punctuation">[</span></summary>').replaceAll('<span class="token punctuation">}</span>','</details><span class="token punctuation inline-block">}</span>').replaceAll('<span class="token punctuation">]</span>','</details><span class="token punctuation inline-block">]</span>')),${p}}return""};function rt(e){const d=e==0?0:Math.floor(Math.log(e)/Math.log(1024));return(e/Math.pow(1024,d)).toFixed(2)*1+"\xA0"+["B","kB","MB","GB","TB"][d]}const ot=e=>{const t=e.toString().replace(/\r\n/g,
| ^
12 | ),c=de(t)?t.replace(/\s/g,""):t;return new Blob([c]).size},nt=e=>{try{return new URL(e)}catch{return null}},W=()=>cy.state("document"),it=,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto},:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.invisible{visibility:hidden}.col-span-1{grid-column:span 1 / span 1}.m-4{margin:1rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mt-6{margin-top:1.5rem}.mt-2{margin-top:.5rem}.mb-2{margin-bottom:.5rem}.inline-block{display:inline-block}.flex{display:flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.w-2\/12{width:16.666667%}.w-24{width:6rem}.w-10\/12{width:83.333333%}.w-full{width:100%}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.gap-4{gap:1rem}.overflow-auto{overflow:auto}.overflow-scroll{overflow:scroll}.break-words{overflow-wrap:break-word}.rounded-sm{border-radius:.125rem}.border{border-width:1px}.border-r{border-right-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-t{border-top-width:1px}.border-slate-800{--tw-border-opacity: 1;border-color:rgb(30 41 59 / var(--tw-border-opacity))}.bg-cy-blue-darker{--tw-bg-opacity: 1;background-color:rgb(27 30 46 / var(--tw-bg-opacity))}.bg-cy-blue-darkest{--tw-bg-opacity: 1;background-color:rgb(23 25 38 / var(--tw-bg-opacity))}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.pl-4{padding-left:1rem}.pb-2{padding-bottom:.5rem}.pr-3{padding-right:.75rem}.pl-1{padding-left:.25rem}.pr-4{padding-right:1rem}.text-left{text-align:left}.align-top{vertical-align:top}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-xs{font-size:.75rem;line-height:1rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-cy-gray{--tw-text-opacity: 1;color:rgb(144 149 173 / var(--tw-text-opacity))}.text-cy-gray-light{--tw-text-opacity: 1;color:rgb(208 210 224 / var(--tw-text-opacity))}.text-cy-green{--tw-text-opacity: 1;color:rgb(31 169 113 / var(--tw-text-opacity))}.text-cy-orange{--tw-text-opacity: 1;color:rgb(219 121 5 / var(--tw-text-opacity))}.text-cy-red{--tw-text-opacity: 1;color:rgb(255 87 112 / var(--tw-text-opacity))}.text-cy-blue{--tw-text-opacity: 1;color:rgb(100 112 243 / var(--tw-text-opacity))}.text-cy-yellow{--tw-text-opacity: 1;color:rgb(237 187 74 / var(--tw-text-opacity))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity))}.outline-0{outline-width:0px}#api-view{position:fixed;top:0px;left:0px;right:0px;bottom:0px;margin-bottom:2.5rem;height:100vh;overflow:scroll;--tw-bg-opacity: 1;background-color:rgb(27 30 46 / var(--tw-bg-opacity));z-index:9999999}@Keyframes fade-out{0%{opacity:1}to{opacity:0}}.cypress-highlight{opacity:.2!important}[data-layer=Padding],[data-layer=Border],[data-layer=Content]{opacity:0!important}[data-layer=Margin]{--tw-bg-opacity: 1 !important;background-color:rgb(254 249 195 / var(--tw-bg-opacity))!important;opacity:0;animation:fade-out 2s ease-in-out}[data-cy=showAuth]:checked+label,[data-cy=showQuery]:checked+label,[data-cy=showRequestHeaders]:checked+label,[data-cy=showRequestBody]:checked+label,[data-cy=showResponseBody]:checked+label,[data-cy=showResponseHeaders]:checked+label,[data-cy=showCookies]:checked+label{--tw-text-opacity: 1;color:rgb(208 210 224 / var(--tw-text-opacity))}[data-cy=showAuth]:checked~[data-cy=auth],[data-cy=showQuery]:checked~[data-cy=query],[data-cy=showRequestHeaders]:checked~[data-cy=requestHeaders],[data-cy=showRequestBody]:checked~[data-cy=requestBody],[data-cy=showResponseBody]:checked~[data-cy=responseBody],[data-cy=showResponseHeaders]:checked~[data-cy=responseHeaders],[data-cy=showCookies]:checked~[data-cy=cookies]{display:block}[data-cy=showAuth]:not(:checked)[data-cy=auth],[data-cy=showQuery]:not(:checked)[data-cy=query],[data-cy=showRequestHeaders]:not(:checked)[data-cy=requestHeaders],[data-cy=showRequestBody]:not(:checked)[data-cy=requestBody],[data-cy=showResponseBody]:not(:checked)[data-cy=responseBody],[data-cy=showResponseHeaders]:not(:checked)[data-cy=responseHeaders],[data-cy=showCookies]:not(:checked)~[data-cy=cookies]{display:none}pre{padding:.75rem;font-size:.75rem;line-height:1rem;--tw-text-opacity: 1;color:rgb(208 210 224 / var(--tw-text-opacity))}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{margin-top:.5rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(30 41 59 / var(--tw-border-opacity));--tw-bg-opacity: 1;background-color:rgb(23 25 38 / var(--tw-bg-opacity));padding-top:1rem;padding-bottom:1rem;padding-left:0;padding-right:1rem}.hljs ::-moz-selection,.hljs::-moz-selection{--tw-bg-opacity: 1;background-color:rgb(46 50 71 / var(--tw-bg-opacity))}.hljs ::selection,.hljs::selection{--tw-bg-opacity: 1;background-color:rgb(46 50 71 / var(--tw-bg-opacity))}.comment{--tw-text-opacity: 1;color:rgb(144 149 173 / var(--tw-text-opacity))}.tag{--tw-text-opacity: 1;color:rgb(100 112 243 / var(--tw-text-opacity))}.operator,.punctuation,.subst{--tw-text-opacity: 1;color:rgb(144 149 173 / var(--tw-text-opacity))}.operator{opacity:.7}.bullet,.deletion,.name,.selector-tag,.template-variable,.variable{--tw-text-opacity: 1;color:rgb(255 87 112 / var(--tw-text-opacity))}.attr,.link,.literal,.number,.symbol,.variable.constant{--tw-text-opacity: 1;color:rgb(208 210 224 / var(--tw-text-opacity))}.number,.attr-name{--tw-text-opacity: 1;color:rgb(31 169 113 / var(--tw-text-opacity))}.attr-value{--tw-text-opacity: 1;color:rgb(208 210 224 / var(--tw-text-opacity))}.addition,.built_in,.code,.doctag,.keyword.atrule,.quote,.regexp,.string,.title.class.inherited__{--tw-text-opacity: 1;color:rgb(100 112 243 / var(--tw-text-opacity))}.diff .meta,.keyword,.template-tag,.type{--tw-text-opacity: 1;color:rgb(127 67 201 / var(--tw-text-opacity))}.meta,.meta .keyword,.meta .string{--tw-text-opacity: 1;color:rgb(144 149 173 / var(--tw-text-opacity))}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{scrollbar-width:none}.line-number{display:inline-block;padding-right:.5rem}details summary{cursor:pointer;--tw-text-opacity: 1;color:rgb(144 149 173 / var(--tw-text-opacity))}code>details:first-of-type>summary{margin-left:-1rem}details[open] summary.brace:before{content:" \25bc ";margin-left:-.5rem;--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity))}details[open] summary.bracket:before{content:" \25bc ";margin-left:-.5rem;--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity))}details:not([open]) summary.brace:before{content:" \25b6\fe0e ";margin-left:-.5rem;--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity))}details:not([open]) summary.bracket:before{content:" \25b6\fe0e ";margin-left:-.5rem;--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity))}details:not([open]) summary.brace:after{content:"\2026";display:inline-block;width:100%}details:not([open]) summary.bracket:after{content:"\2026";display:inline-block;width:100%}details:not([open]){display:inline-block}
13 | ,st=,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto},:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.invisible{visibility:hidden}.col-span-1{grid-column:span 1 / span 1}.m-4{margin:1rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mt-6{margin-top:1.5rem}.mt-2{margin-top:.5rem}.mb-2{margin-bottom:.5rem}.inline-block{display:inline-block}.flex{display:flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.w-2\/12{width:16.666667%}.w-24{width:6rem}.w-10\/12{width:83.333333%}.w-full{width:100%}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.gap-4{gap:1rem}.overflow-auto{overflow:auto}.overflow-scroll{overflow:scroll}.break-words{overflow-wrap:break-word}.rounded-sm{border-radius:.125rem}.border{border-width:1px}.border-r{border-right-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-t{border-top-width:1px}.border-slate-800{--tw-border-opacity: 1;border-color:rgb(30 41 59 / var(--tw-border-opacity))}.bg-cy-blue-darker{--tw-bg-opacity: 1;background-color:rgb(27 30 46 / var(--tw-bg-opacity))}.bg-cy-blue-darkest{--tw-bg-opacity: 1;background-color:rgb(23 25 38 / var(--tw-bg-opacity))}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.pl-4{padding-left:1rem}.pb-2{padding-bottom:.5rem}.pr-3{padding-right:.75rem}.pl-1{padding-left:.25rem}.pr-4{padding-right:1rem}.text-left{text-align:left}.align-top{vertical-align:top}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-xs{font-size:.75rem;line-height:1rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-cy-gray{--tw-text-opacity: 1;color:rgb(144 149 173 / var(--tw-text-opacity))}.text-cy-gray-light{--tw-text-opacity: 1;color:rgb(208 210 224 / var(--tw-text-opacity))}.text-cy-green{--tw-text-opacity: 1;color:rgb(31 169 113 / var(--tw-text-opacity))}.text-cy-orange{--tw-text-opacity: 1;color:rgb(219 121 5 / var(--tw-text-opacity))}.text-cy-red{--tw-text-opacity: 1;color:rgb(255 87 112 / var(--tw-text-opacity))}.text-cy-blue{--tw-text-opacity: 1;color:rgb(100 112 243 / var(--tw-text-opacity))}.text-cy-yellow{--tw-text-opacity: 1;color:rgb(237 187 74 / var(--tw-text-opacity))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity))}.outline-0{outline-width:0px}.command.command-name-GET span.command-method{border-radius:.125rem;--tw-bg-opacity: 1;background-color:rgb(100 112 243 / var(--tw-bg-opacity));padding-left:.375rem;padding-right:.375rem;color:#fff!important;min-width:10px;margin-right:6px}.command.command-name-DELETE span.command-method{border-radius:.125rem;--tw-bg-opacity: 1;background-color:rgb(255 87 112 / var(--tw-bg-opacity));padding-left:.375rem;padding-right:.375rem;color:#fff!important;min-width:10px;margin-right:6px}.command.command-name-PATCH span.command-method{border-radius:.125rem;--tw-bg-opacity: 1;background-color:rgb(219 121 5 / var(--tw-bg-opacity));padding-left:.375rem;padding-right:.375rem;color:#fff!important;min-width:10px;margin-right:6px}.command.command-name-HEAD span.command-method{border-radius:.125rem;--tw-bg-opacity: 1;background-color:rgb(237 187 74 / var(--tw-bg-opacity));padding-left:.375rem;padding-right:.375rem;color:#fff!important;min-width:10px;margin-right:6px}.command.command-name-PUT span.command-method,.command.command-name-POST span.command-method{border-radius:.125rem;--tw-bg-opacity: 1;background-color:rgb(31 169 113 / var(--tw-bg-opacity));padding-left:.375rem;padding-right:.375rem;color:#fff!important;min-width:10px;margin-right:6px}
14 | ,lt=()=>{const e=W(),d=e.head||e.getElementsByTagName("head")[0],t=e.createElement("style");d.appendChild(t),t.appendChild(e.createTextNode(it));const c=(top==null?void 0:top.document.querySelector("#unified-reporter"))||(top==null?void 0:top.document.querySelector("#app")),p=document.createElement("style");c==null||c.appendChild(p),p.appendChild(e.createTextNode(st))},dt=e=>{const d=W();lt();const t=d.createElement("div");t.setAttribute("id","api-plugin-root"),d.body.appendChild(t);const c=d.getElementById("api-plugin-root");e.mount(c)},ct=()=>{W().getElementsByTagName("style")[0].remove()};var L={exports:{}},P={decodeValues:!0,map:!1,silent:!1};function te(e){return typeof e=="string"&&!!e.trim()}function ae(e,d){var t=e.split(";").filter(te),c=t.shift(),p=ut(c),b=p.name,f=p.value;d=d?Object.assign({},P,d):P;try{f=d.decodeValues?decodeURIComponent(f):f}catch(u){console.error("set-cookie-parser encountered an error while decoding a cookie with value '"+f+"'. Set options.decodeValues to false to disable this feature.",u)}var i={name:b,value:f};return t.forEach(function(u){var x=u.split("="),v=x.shift().trimLeft().toLowerCase(),h=x.join("=");v==="expires"?i.expires=new Date(h):v==="max-age"?i.maxAge=parseInt(h,10):v==="secure"?i.secure=!0:v==="httponly"?i.httpOnly=!0:v==="samesite"?i.sameSite=h:i[v]=h}),i}function ut(e){var d="",t="",c=e.split("=");return c.length>1?(d=c.shift(),t=c.join("=")):t=e,{name:d,value:t}}function ce(e,d){if(d=d?Object.assign({},P,d):P,!e)return d.map?{}:[];if(e.headers&&e.headers["set-cookie"])e=e.headers["set-cookie"];else if(e.headers){var t=e.headers[Object.keys(e.headers).find(function(p){return p.toLowerCase()==="set-cookie"})];!t&&e.headers.cookie&&!d.silent&&console.warn("Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning."),e=t}if(Array.isArray(e)||(e=[e]),d=d?Object.assign({},P,d):P,d.map){var c={};return e.filter(te).reduce(function(p,b){var f=ae(b,d);return p[f.name]=f,p},c)}else return e.filter(te).map(function(p){return ae(p,d)})}function pt(e){if(Array.isArray(e))return e;if(typeof e!="string")return[];var d=[],t=0,c,p,b,f,i;function u(){for(;t<e.length&&/\s/.test(e.charAt(t));)t+=1;return t<e.length}function x(){return p=e.charAt(t),p!=="="&&p!==";"&&p!==","}for(;t<e.length;){for(c=t,i=!1;u();)if(p=e.charAt(t),p===","){for(b=t,t+=1,u(),f=t;t<e.length&&x();)t+=1;t<e.length&&e.charAt(t)==="="?(i=!0,t=f,d.push(e.substring(c,b)),c=t):t=b+1}else t+=1;(!i||t>=e.length)&&d.push(e.substring(c,e.length))}return d}L.exports=ce;L.exports.parse=ce;L.exports.parseString=ae;L.exports.splitCookiesString=pt;const{_:R}=Cypress;before(()=>{window.props={}});const le=(e,...d)=>{var A;const t=Cypress.currentTest.titlePath.join("."),p=cy.state("runnable")._currentRetry!==0,b=!!((A=window.props[t])!=null&&A.length),f=b&&!p?window.props[t]:[],i=W(),u=r.reactive(f),x=r.createApp(Xe,{props:u});(!b||p||Cypress.env("snapshotOnly"))&&dt(x);const v=X(...d),h=u.length,C={id:R.uniqueId(),method:"GET",status:"",time:0,size:"",url:"",auth:{body:{},formatted:""},query:{body:{},formatted:""},requestHeaders:{body:{},formatted:""},requestBody:{body:{},formatted:""},responseBody:{body:{},formatted:""},responseHeaders:{body:{},formatted:""},cookies:{body:{}}};u.push(C),u[h].method=R.cloneDeep(v.method)||"GET",u[h].url=nt(v.url)?v.url:Cypress.config("baseUrl")+v.url,u[h].query.body=R.cloneDeep(v.qs),u[h].auth.body=R.cloneDeep(v.auth),u[h].requestHeaders.body=R.cloneDeep(v.headers),u[h].requestBody.body=R.cloneDeep(v.body),Cypress.env("hideCredentials")&&(u[h]=at(u[h])),u[h].requestBody.formatted=j(u[h].requestBody.body),u[h].requestHeaders.formatted=j(u[h].requestHeaders.body),u[h].query.formatted=j(u[h].query.body),u[h].auth.formatted=j(u[h].auth.body);let N;const q=Cypress.log({name:v.method||"GET",autoEnd:!1,message:${v.url}});return cy.wrap(e({...v,log:!1},v),{log:!1,timeout:v.timeout||Cypress.config("responseTimeout")}).then(w=>{const{body:k,status:o,headers:a,statusText:n,duration:s}=w,l=${o}\xA0(${n});u[h].status=l||"",u[h].time=s;const g=a["content-type"],y=a["content-length"],m=a["set-cookie"],F=typeof k==="object"?JSON.stringify(k,null,2):k;if(g){const H=g.split(";")[0],Z={"text/xml":"xml","application/json":"json","text/html":"html","text/plain":"plaintext"}[H];u[h].responseBody.formatted=j(k,Z),u[h].responseBody.body=F}const $=L.exports.parse(m,{decodeValues:!0});u[h].cookies.body=$,u[h].requestBody.formatted.length||(u[h].requestBody.formatted='<div class="pl-4 text-cy-gray text-xs font-mono">(No content)</div>'),u[h].responseBody.formatted.length||(u[h].responseBody.formatted='<div class="pl-4 text-cy-gray text-xs font-mono">(No content)</div>'),u[h].responseHeaders.body=a,u[h].responseHeaders.formatted=j(a);const M=y?parseInt(y):ot(u[h].responseBody.body);u[h].size=rt(M),w.size=M,N=w,cy.get(#${u[h].id},{log:!1}).then(H=>{var D;return q.set({consoleProps(){return{yielded:N}}}),window.props[t]=u,q.set({$el:H}),q.snapshot("snapshot").end(),(D=i.getElementById("api-view-bottom"))==null||D.scrollIntoView(),Cypress.env("snapshotOnly")&&(x.unmount(),ct()),w})})};Cypress.env("requestMode")?(Cypress.Commands.overwrite("request",le),Cypress.Commands.add("api",(...e)=>{const d=X(...e);return cy.request({...d,log:!1})})):Cypress.Commands.add("api",(...e)=>{Cypress.Commands.overwrite("request",le);const d=X(...e);return cy.request({...d,log:!1})});const gt=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));module.exports=gt;

When in snapshot, tabs are not interactive

steps to reproduce:

  1. run a test at least with two api calls
  2. in timeline click on the first one
  3. try to interact with tabs
  4. tabs not responding

when highlight toggle at the bottom of the snapshot is off, interactivity works. probably highlight element covers it

[Bug] Invalidation of Printed Information

Hi Filip! We use this plugin with cypress-cucumber-preprocessor together in our project. There are of course multiple scenarios in our feature files. But the printed information of requests belongs to previous scenarios have been overriding until the last scenario executes. Well, only requests for the last scenario has can be viewed. Do you have any solution for this? Thanks.

Cypress version: 11.0.1
Preproccessor version: 14.0.0
Plugin version: 2.3.3

e2e: {
    setupNodeEvents,
    snapshotOnly: true,
    excludeSpecPattern: '*.js',
    specPattern: '**/*.feature',
    experimentalSessionAndOrigin: true,
    experimentalWebKitSupport: true,
    experimentalInteractiveRunEvents: true,
    requestMode: true,
  }

UI view dos not work when `experimentalSessionAndOrigin` flag is set to `true`

Apparently when experimentalSessionAndOrigin flag is enabled, there’s some other screen shown in the UI view. It informs the user that about:blank page was visited in between tests. For some reason the current state of the plugin is not able to handle it. Needs to be fixed as this may go to general availability soon and visiting empty page may become default behavior.

Cypress App preview is stuck on API calls screen

Hi Filip,
we use cypress-plugin-api v2.3.3 + Cypress v 11.0.1 and there is issue of Cypress App preview not switching back to tested application after making api calls.

We have tests for application front-end, it just simulates user behavior but at some point we make api calls to make something happen on the background. After these api calls, test should continue in testing application front-end. Unfortunately, in Cypress App preview, the screen is stuck on API calls view and doesn't go back to tested APP and fails.

Could you please take a look at it? Thanks!

Interactive response body

For assessing the response payloads, it would be awesome if the JSON was interactive - particularly the ability to collapse sections and navigate the document as you would in an IDE.

Add the ability to hide the authorization

When running API tests with the cypress-plugin-api, if authorization is needed (where it would have an API key, for example), such info is displayed in the Headers section.

For security reasons, it'd be nice to have the ability to hide such information.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.