add missing TypeScript jsdocs for types for issue 2009 (#2137)

* doc second cy.find type

* document type for cy.request

* document Cypress.env command

* doc type for Cypress.log

* doc types for uncheck

* add type docs for cy.spy

* document spies and stubs types

* add space to align jsdoc stars

* types: show to correctly pass request options, close #2093

* cast just the http method property

* types for spy withArgs and as

* doc more types for overrides

* type for spread

* type for overriden then

* types for cy.trigger overrides

* rest of types of overriden methods, close #2009
This commit is contained in:
Gleb Bahmutov
2018-07-13 00:42:50 +02:00
committed by Brian Mann
parent a97d9be210
commit 7a2c21144f
2 changed files with 380 additions and 10 deletions

360
cli/types/index.d.ts vendored
View File

@@ -163,13 +163,41 @@ declare namespace Cypress {
// no real way to type without generics
/**
* Returns all environment variables set with CYPRESS_ prefix or in "env" object in "cypress.json"
*
* @see https://on.cypress.io/env
*/
env(): ObjectLike
/**
* Returns specific environment variable or undefined
* @see https://on.cypress.io/env
* @example
* // cypress.json
* { "env": { "foo": "bar" } }
* Cypress.env("foo") // => bar
*/
env(key: string): any
/**
* Set value for a variable.
* Any value you change will be permanently changed for the remainder of your tests.
* @see https://on.cypress.io/env
* @example
* Cypress.env("host", "http://server.dev.local")
*/
env(key: string, value: any): void
/**
* Set values for multiple variables at once. Values are merged with existing values.
* @see https://on.cypress.io/env
* @example
* Cypress.env({ host: "http://server.dev.local", foo: "foo" })
*/
env(object: ObjectLike): void
/**
* Internal options for "cy.log" used in custom commands.
*
* @see https://on.cypress.io/cypress-log
*/
log(options: Partial<LogConfig>): Log
/**
@@ -449,6 +477,14 @@ declare namespace Cypress {
* cy.contains('ul', 'apples')
*/
contains(content: string | number | RegExp): Chainable<Subject>
/**
* Get the child DOM element that contains given text.
*
* @see https://on.cypress.io/contains
* @example
* // Yield el in .nav containing 'About'
* cy.get('.nav').contains('About')
*/
contains<E extends Node = HTMLElement>(content: string | number | RegExp): Chainable<JQuery<E>>
/**
* Get the DOM element with name "selector" containing the text or regular expression.
@@ -533,7 +569,17 @@ declare namespace Cypress {
* @see https://on.cypress.io/filter
*/
filter<K extends keyof HTMLElementTagNameMap>(selector: K, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<HTMLElementTagNameMap[K]>> // automatically returns the correct HTMLElement type
/**
* Get the DOM elements that match a specific selector. Opposite of `.not()`
*
* @see https://on.cypress.io/filter
*/
filter<E extends Node = HTMLElement>(selector: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
* Get the DOM elements that match a specific selector. Opposite of `.not()`
*
* @see https://on.cypress.io/filter
*/
filter<E extends Node = HTMLElement>(fn: (index: number, element: E) => boolean, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
@@ -544,6 +590,14 @@ declare namespace Cypress {
* cy.get('.article').find('footer') // Yield 'footer' within '.article'
*/
find<K extends keyof HTMLElementTagNameMap>(selector: K, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<HTMLElementTagNameMap[K]>>
/**
* Finds the descendent DOM elements with the given selector.
*
* @see https://on.cypress.io/find
* @example
* // Find the lis within the nav
* cy.get('.left-nav>.nav').find('>li')
*/
find<E extends Node = HTMLElement>(selector: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
@@ -559,6 +613,11 @@ declare namespace Cypress {
* @see https://on.cypress.io/fixture
*/
fixture<Contents = any>(path: string, options?: Partial<Timeoutable>): Chainable<Contents> // no log?
/**
* Load a fixed set of data located in a file with given encoding.
*
* @see https://on.cypress.io/fixture
*/
fixture<Contents = any>(path: string, encoding: Encodings, options?: Partial<Timeoutable>): Chainable<Contents> // no log?
/**
@@ -676,8 +735,18 @@ declare namespace Cypress {
* Get the global `window.location` object of the page that is currently active.
*
* @see https://on.cypress.io/location
* @example
* cy.location() // Get location object
*/
location(options?: Partial<Loggable & Timeoutable>): Chainable<Location>
/**
* Get a part of the global `window.location` object of the page that is currently active.
*
* @see https://on.cypress.io/location
* @example
* cy.location('host') // Get the host of the location object
* cy.location('port') // Get the port of the location object
*/
location(key: string, options?: Partial<Loggable & Timeoutable>): Chainable<Location>
/**
@@ -716,7 +785,17 @@ declare namespace Cypress {
* @see https://on.cypress.io/nextall
*/
nextAll<K extends keyof HTMLElementTagNameMap>(selector: K, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<HTMLElementTagNameMap[K]>>
/**
* Get all following siblings of each DOM element in a set of matched DOM elements.
*
* @see https://on.cypress.io/nextall
*/
nextAll<E extends HTMLElement = HTMLElement>(options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
* Get all following siblings of each DOM element in a set of matched DOM elements.
*
* @see https://on.cypress.io/nextall
*/
nextAll<E extends HTMLElement = HTMLElement>(selector: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
@@ -725,7 +804,17 @@ declare namespace Cypress {
* @see https://on.cypress.io/nextuntil
*/
nextUntil<K extends keyof HTMLElementTagNameMap>(selector: K, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<HTMLElementTagNameMap[K]>>
/**
* Get all following siblings of each DOM element in a set of matched DOM elements up to, but not including, the element provided.
*
* @see https://on.cypress.io/nextuntil
*/
nextUntil<E extends HTMLElement = HTMLElement>(options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
* Get all following siblings of each DOM element in a set of matched DOM elements up to, but not including, the element provided.
*
* @see https://on.cypress.io/nextuntil
*/
nextUntil<E extends HTMLElement = HTMLElement>(selector: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
@@ -753,7 +842,17 @@ declare namespace Cypress {
* @see https://on.cypress.io/parent
*/
parent<K extends keyof HTMLElementTagNameMap>(selector: K, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<HTMLElementTagNameMap[K]>>
/**
* Get the parent DOM element of a set of DOM elements.
*
* @see https://on.cypress.io/parent
*/
parent<E extends Node = HTMLElement>(options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
* Get the parent DOM element of a set of DOM elements.
*
* @see https://on.cypress.io/parent
*/
parent<E extends Node = HTMLElement>(selector: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
@@ -762,7 +861,17 @@ declare namespace Cypress {
* @see https://on.cypress.io/parents
*/
parents<K extends keyof HTMLElementTagNameMap>(selector: K, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<HTMLElementTagNameMap[K]>>
/**
* Get the parent DOM elements of a set of DOM elements.
*
* @see https://on.cypress.io/parents
*/
parents<E extends Node = HTMLElement>(options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
* Get the parent DOM elements of a set of DOM elements.
*
* @see https://on.cypress.io/parents
*/
parents<E extends Node = HTMLElement>(selector: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
@@ -771,7 +880,17 @@ declare namespace Cypress {
* @see https://on.cypress.io/parentsuntil
*/
parentsUntil<K extends keyof HTMLElementTagNameMap>(selector: K, filter?: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<HTMLElementTagNameMap[K]>>
/**
* Get all ancestors of each DOM element in a set of matched DOM elements up to, but not including, the element provided.
*
* @see https://on.cypress.io/parentsuntil
*/
parentsUntil<E extends Node = HTMLElement>(selector: string, filter?: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
* Get all ancestors of each DOM element in a set of matched DOM elements up to, but not including, the element provided.
*
* @see https://on.cypress.io/parentsuntil
*/
parentsUntil<E extends Node = HTMLElement>(element: E | JQuery<E>, filter?: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
@@ -814,7 +933,19 @@ declare namespace Cypress {
* @see https://on.cypress.io/prevall
*/
prevAll<K extends keyof HTMLElementTagNameMap>(selector: K, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<HTMLElementTagNameMap[K]>>
/**
* Get all previous siblings of each DOM element in a set of matched DOM elements.
* > The querying behavior of this command matches exactly how [.prevAll()](http://api.jquery.com/prevAll) works in jQuery.
*
* @see https://on.cypress.io/prevall
*/
prevAll<E extends Node = HTMLElement>(options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
* Get all previous siblings of each DOM element in a set of matched DOM elements.
* > The querying behavior of this command matches exactly how [.prevAll()](http://api.jquery.com/prevAll) works in jQuery.
*
* @see https://on.cypress.io/prevall
*/
prevAll<E extends Node = HTMLElement>(selector: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
@@ -824,7 +955,19 @@ declare namespace Cypress {
* @see https://on.cypress.io/prevall
*/
prevUntil<K extends keyof HTMLElementTagNameMap>(selector: K, filter?: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<HTMLElementTagNameMap[K]>>
/**
* Get all previous siblings of each DOM element in a set of matched DOM elements up to, but not including, the element provided.
* > The querying behavior of this command matches exactly how [.prevUntil()](http://api.jquery.com/prevUntil) works in jQuery.
*
* @see https://on.cypress.io/prevall
*/
prevUntil<E extends Node = HTMLElement>(selector: string, filter?: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
* Get all previous siblings of each DOM element in a set of matched DOM elements up to, but not including, the element provided.
* > The querying behavior of this command matches exactly how [.prevUntil()](http://api.jquery.com/prevUntil) works in jQuery.
*
* @see https://on.cypress.io/prevall
*/
prevUntil<E extends Node = HTMLElement>(element: E | JQuery<E>, filter?: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
@@ -833,6 +976,13 @@ declare namespace Cypress {
* @see https://on.cypress.io/readfile
*/
readFile<Contents = any>(filePath: string, options?: Partial<Loggable & Timeoutable>): Chainable<Contents>
/**
* Read a file with given encoding and yield its contents.
*
* @see https://on.cypress.io/readfile
* @example
* cy.readFile('foo.json', 'utf8')
*/
readFile<Contents = any>(filePath: string, encoding: Encodings, options?: Partial<Loggable & Timeoutable>): Chainable<Contents>
/**
@@ -856,12 +1006,31 @@ declare namespace Cypress {
reload(forceReload: boolean): Chainable<Window>
/**
* Make an HTTP request.
* Make an HTTP GET request.
*
* @see https://on.cypress.io/request
* @example
* cy.request('http://dev.local/seed')
*/
request(url: string, body?: RequestBody): Chainable<Response>
/**
* Make an HTTP request with specific method.
*
* @see https://on.cypress.io/request
* @example
* cy.request('POST', 'http://localhost:8888/users', {name: 'Jane'})
*/
request(method: HttpMethod, url: string, body?: RequestBody): Chainable<Response>
/**
* Make an HTTP request with specific behavior.
*
* @see https://on.cypress.io/request
* @example
* cy.request({
* url: '/dashboard',
* followRedirect: false // turn off following redirects
* })
*/
request(options: Partial<RequestOptions>): Chainable<Response>
/**
@@ -958,14 +1127,24 @@ declare namespace Cypress {
* @see https://on.cypress.io/scrollto
*/
scrollTo(position: PositionType, options?: Partial<ScrollToOptions>): Chainable<Subject>
/**
* Scroll to a specific X,Y position.
*
* @see https://on.cypress.io/scrollto
*/
scrollTo(x: number | string, y: number | string, options?: Partial<ScrollToOptions>): Chainable<Subject>
/**
* Select an `<option>` within a `<select>`.
* Select an `<option>` with specific text within a `<select>`.
*
* @see https://on.cypress.io/select
*/
select(text: string | string[], options?: Partial<SelectOptions>): Chainable<Subject>
/**
* Select an `<option>` with specific value(s) within a `<select>`.
*
* @see https://on.cypress.io/select
*/
select(value: string | string[], options?: Partial<SelectOptions>): Chainable<Subject>
/**
@@ -1027,29 +1206,85 @@ declare namespace Cypress {
siblings<E extends Node = HTMLElement>(selector: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
/**
* Wrap a method in a spy in order to record calls to and arguments of the function.
* > Note: `.spy()` assumes you are already familiar with our guide: [Stubs, Spies, and Clocks](https://docs.cypress.io/guides/guides/stubs-spies-and-clocks.html)
* Returns a new spy function.
* > Note: `.spy()` assumes you are already familiar with our guide: [Stubs, Spies, and Clocks](https://on.cypress.io/stubs-spies-and-clocks)
*
* @see https://on.cypress.io/spy
* @example
* const fn = cy.spy() // returns "dumb" spy function
* fn(42)
* expect(fn).to.have.been.calledOnce
* expect(fn).to.have.always.been.calledWithExactly(42)
*/
spy(): Agent<sinon.SinonSpy>
/**
* Wraps existing function and spies on it, while passing arguments and results.
* @see https://on.cypress.io/spy
* @example
* const add = (a, b) => a + b
* const spy = cy.spy(add)
* expect(spy(2, 3)).to.equal(5)
* expect(spy).to.have.been.calledWithExactly(2, 3)
*/
spy(func: (...args: any[]) => any): Agent<sinon.SinonSpy>
/**
* Spy on a method.
* @see https://on.cypress.io/spy
* @example
* // assume App.start calls util.addListeners
* cy.spy(util, 'addListeners')
* App.start()
* expect(util.addListeners).to.be.called
* @see https://on.cypress.io/spy
*/
spy(): Agent<sinon.SinonSpy>
spy(func: (...args: any[]) => any): Agent<sinon.SinonSpy>
spy<T>(obj: T, method: keyof T): Agent<sinon.SinonSpy>
/**
* Replace a function, record its usage and control its behavior.
* > Note: `.stub()` assumes you are already familiar with our guide: [Stubs, Spies, and Clocks](https://docs.cypress.io/guides/guides/stubs-spies-and-clocks.html)
* > Note: `.stub()` assumes you are already familiar with our guide:
* [Stubs, Spies, and Clocks](https://on.cypress.io/stubs-spies-and-clocks)
*
* @see https://on.cypress.io/stub
* @example
* const fn = cy.stub() // stub without any arguments acts like a spy
* fn(42)
* expect(fn).to.have.been.calledOnce
* expect(fn).to.have.always.been.calledWithExactly(42)
*/
stub(): Agent<sinon.SinonStub>
/**
* Stubs all the objects methods.
*
* @see https://on.cypress.io/stub
* @example
* const o = {
* toString () {
* return 'foo'
* }
* }
* expect(o.toString()).to.equal('foo')
* cy.stub(o)
* // because stub does not call original function
* expect(o.toString()).to.equal(undefined)
* expect(o.toString).to.have.been.calledOnce
*/
stub(obj: any): Agent<sinon.SinonStub>
/**
* Stubs single method of an object.
*
* @see https://on.cypress.io/stub
* @example
* const o = {}
* expect(o.toString()).to.equal('[object Object]')
* cy.stub(o, 'toString').callsFake(() => 'foo')
* expect(o.toString()).to.equal('foo')
* expect(o.toString).to.have.been.calledOnce
*/
stub<T>(obj: T, method: keyof T): Agent<sinon.SinonStub>
/**
* Stubs a method on an object
*
* @deprecated Use `cy.stub(object, name).callsFake(fn)` instead
*/
stub<T>(obj: T, method: keyof T, func: (...args: any[]) => any): Agent<sinon.SinonStub>
/**
@@ -1059,7 +1294,23 @@ declare namespace Cypress {
*/
submit(options?: Partial<Loggable & Timeoutable>): Chainable<Subject>
/**
* Expand an array into multiple arguments.
* @see https://on.cypress.io/spread
* @example
* cy.getCookies().spread((cookie1, cookie2, cookie3) => {
* // each cookie is now an individual argument
* })
*/
spread<S extends object | any[] | string | number | boolean>(fn: (...args: any[]) => S): Chainable<S>
/**
* Expand an array into multiple arguments.
* @see https://on.cypress.io/spread
* @example
* cy.getCookies().spread((cookie1, cookie2, cookie3) => {
* // each cookie is now an individual argument
* })
*/
spread(fn: (...args: any[]) => void): Chainable<Subject>
/**
@@ -1075,7 +1326,17 @@ declare namespace Cypress {
* @see https://on.cypress.io/then
*/
then<S>(fn: (this: ObjectLike, currentSubject: Subject) => Chainable<S>, options?: Partial<Timeoutable>): Chainable<S>
/**
* Enables you to work with the subject yielded from the previous command / promise.
*
* @see https://on.cypress.io/then
*/
then<S>(fn: (this: ObjectLike, currentSubject: Subject) => PromiseLike<S>, options?: Partial<Timeoutable>): Chainable<S>
/**
* Enables you to work with the subject yielded from the previous command / promise.
*
* @see https://on.cypress.io/then
*/
then<S extends object | any[] | string | number | boolean>(fn: (this: ObjectLike, currentSubject: Subject) => S, options?: Partial<Timeoutable>): Chainable<S>
/**
* Enables you to work with the subject yielded from the previous command.
@@ -1108,11 +1369,47 @@ declare namespace Cypress {
* @see https://on.cypress.io/trigger
*/
trigger<K extends keyof DocumentEventMap>(eventName: K, options?: Partial<TriggerOptions & DocumentEventMap[K]>): Chainable<Subject>
/**
* Trigger an event on a DOM element.
*
* @see https://on.cypress.io/trigger
*/
trigger<K extends keyof DocumentEventMap>(eventName: K, position?: PositionType, options?: Partial<TriggerOptions & DocumentEventMap[K]>): Chainable<Subject>
/**
* Trigger an event on a DOM element.
*
* @see https://on.cypress.io/trigger
*/
trigger<K extends keyof DocumentEventMap>(eventName: K, x: number, y: number, options?: Partial<TriggerOptions & DocumentEventMap[K]>): Chainable<Subject>
// custom events... If the following were `.triggerCustom`, `.trigger` strongly typed with event data
/**
* Trigger an event on a DOM element.
* Custom events... If the following were `.triggerCustom`,
* `.trigger` strongly typed with event data
*
* @see https://on.cypress.io/trigger
* @example
* cy.get('a').trigger('mousedown')
*/
trigger(eventName: string, position?: PositionType, options?: Partial<TriggerOptions>): Chainable<Subject>
/**
* Trigger an event on a DOM element.
* Custom events... If the following were `.triggerCustom`,
* `.trigger` strongly typed with event data
*
* @see https://on.cypress.io/trigger
* @example
* cy.get('a').trigger('mousedown')
*/
trigger(eventName: string, options?: Partial<TriggerOptions & ObjectLike>): Chainable<Subject>
/**
* Trigger an event on a DOM element.
* Custom events... If the following were `.triggerCustom`,
* `.trigger` strongly typed with event data
*
* @see https://on.cypress.io/trigger
* @example
* cy.get('a').trigger('mousedown')
*/
trigger(eventName: string, x: number, y: number, options?: Partial<TriggerOptions>): Chainable<Subject>
/**
@@ -1141,7 +1438,23 @@ declare namespace Cypress {
* cy.get('input[type="checkbox"]').uncheck(['ga'])
*/
uncheck(options?: Partial<CheckOptions>): Chainable<Subject>
/**
* Uncheck specific checkbox.
*
* @see https://on.cypress.io/uncheck
* @example
* // Uncheck the checkbox with the value of ga
* cy.get('input[type="checkbox"]').uncheck('ga')
*/
uncheck(value: string, options?: Partial<CheckOptions>): Chainable<Subject>
/**
* Uncheck specific checkboxes.
*
* @see https://on.cypress.io/uncheck
* @example
* // Uncheck the checkbox with the value of ga, 'ma'
* cy.get('input[type="checkbox"]').uncheck(['ga', 'ma'])
*/
uncheck(values: string[], options?: Partial<CheckOptions>): Chainable<Subject>
/**
@@ -1221,7 +1534,8 @@ declare namespace Cypress {
window(options?: Partial<Loggable & Timeoutable>): Chainable<Window>
/**
* Scopes all subsequent cy commands to within this element. Useful when working within a particular group of elements such as a `<form>`.
* Scopes all subsequent cy commands to within this element.
* Useful when working within a particular group of elements such as a `<form>`.
* @see https://on.cypress.io/within
* @example
* cy.get('form').within(($form) => {
@@ -1234,6 +1548,11 @@ declare namespace Cypress {
*
*/
within(fn: (currentSubject: Subject) => void): Chainable<Subject>
/**
* Scopes all subsequent cy commands to within this element.
* Useful when working within a particular group of elements such as a `<form>`.
* @see https://on.cypress.io/within
*/
within(options: Partial<Loggable>, fn: (currentSubject: Subject) => void): Chainable<Subject> // inconsistent argument order
/**
@@ -1265,14 +1584,35 @@ declare namespace Cypress {
* @see https://on.cypress.io/writefile
*/
writeFile<C extends FileContents>(filePath: string, contents: C, options?: Partial<Loggable>): Chainable<C>
/**
* Write to a file with the specified encoding and contents.
*
* @see https://on.cypress.io/writefile
*/
writeFile<C extends FileContents>(filePath: string, contents: C, encoding: Encodings, options?: Partial<Loggable>): Chainable<C>
}
interface Agent<A extends sinon.SinonSpy> {
log(shouldOutput?: boolean): Omit<A, 'withArgs'> & Agent<A>
/**
* Saves current spy / stub under an alias.
* @see https://on.cypress.io/stubs-spies-and-clocks
* @see https://on.cypress.io/as
* @example
* cy.spy(win, 'fetch').as('winFetch') // Alias 'window.fetch' spy as "winFetch"
*/
as(alias: string): Omit<A, 'withArgs'> & Agent<A>
/**
* Creates a spy / stub but only for calls with given arguments.
* @see https://on.cypress.io/stubs-spies-and-clocks
* @see https://on.cypress.io/as
* @example
* const s = cy.stub(JSON, 'parse').withArgs('invalid').returns(42)
* expect(JSON.parse('invalid')).to.equal(42)
* expect(s).to.have.been.calledOnce
*/
withArgs(...args: any[]): Omit<A, 'withArgs'> & Agent<A>
}

View File

@@ -47,3 +47,33 @@ cy.on('window:alert', cy.stub())
// window:confirm stubbing
cy.on('window:confirm', () => {})
cy.on('window:confirm', cy.stub())
// specifying HTTP method directly in the options object
cy.request({
url: "http://localhost:3000/myressource",
method: "POST",
body: {}
})
// if you want a separate variable, you need specify its type
// otherwise TSC does not cast string "POST" as HttpMethod
// https://github.com/cypress-io/cypress/issues/2093
const opts: Partial<Cypress.RequestOptions> = {
url: "http://localhost:3000/myressource",
method: "POST",
body: {}
}
cy.request(opts)
// you can cast just the "method" property
const opts2 = {
url: "http://localhost:3000/myressource",
method: "POST" as Cypress.HttpMethod,
body: {}
}
cy.request(opts2)
const obj = {
foo: () => {}
}
cy.spy(obj, 'foo').as('my-spy')