mirror of
https://github.com/cypress-io/cypress.git
synced 2026-04-22 07:00:22 -05:00
feat: Add cy.getAllCookies() and cy.clearAllCookies() (#25012)
This commit is contained in:
Vendored
+43
-9
@@ -896,21 +896,41 @@ declare namespace Cypress {
|
||||
clear(options?: Partial<ClearOptions>): Chainable<Subject>
|
||||
|
||||
/**
|
||||
* Clear a specific browser cookie for the current hostname or for the domain specified.
|
||||
* Cypress automatically clears all cookies before each test to prevent state from being shared across tests. You shouldn't need to use this command unless you're using it to clear a specific cookie inside a single test.
|
||||
* Clear a specific browser cookie for a domain.
|
||||
*
|
||||
* Cypress automatically clears all cookies _before_ each test to prevent
|
||||
* state from being shared across tests when test isolation is enabled.
|
||||
* You shouldn't need to use this command unless you're using it to clear
|
||||
* a specific cookie inside a single test or test isolation is disabled.
|
||||
*
|
||||
* @see https://on.cypress.io/clearcookie
|
||||
*/
|
||||
clearCookie(name: string, options?: CookieOptions): Chainable<null>
|
||||
|
||||
/**
|
||||
* Clear all browser cookies for the current hostname or for the domain specified.
|
||||
* Cypress automatically clears all cookies before each test to prevent state from being shared across tests. You shouldn't need to use this command unless you're using it to clear all cookies or specific cookies inside a single test.
|
||||
* Clear browser cookies for a domain.
|
||||
*
|
||||
* Cypress automatically clears all cookies _before_ each test to prevent
|
||||
* state from being shared across tests when test isolation is enabled.
|
||||
* You shouldn't need to use this command unless you're using it to clear
|
||||
* specific cookies inside a single test or test isolation is disabled.
|
||||
*
|
||||
* @see https://on.cypress.io/clearcookies
|
||||
*/
|
||||
clearCookies(options?: CookieOptions): Chainable<null>
|
||||
|
||||
/**
|
||||
* Clear all browser cookies.
|
||||
*
|
||||
* Cypress automatically clears all cookies _before_ each test to prevent
|
||||
* state from being shared across tests when test isolation is enabled.
|
||||
* You shouldn't need to use this command unless you're using it to clear
|
||||
* all cookie inside a single test or test isolation is disabled.
|
||||
*
|
||||
* @see https://on.cypress.io/clearallcookies
|
||||
*/
|
||||
clearAllCookies(options?: Partial<Loggable & Timeoutable>): Chainable<null>
|
||||
|
||||
/**
|
||||
* Get local storage for all origins.
|
||||
*
|
||||
@@ -921,6 +941,11 @@ declare namespace Cypress {
|
||||
/**
|
||||
* Clear local storage for all origins.
|
||||
*
|
||||
* Cypress automatically clears all local storage _before_ each test to
|
||||
* prevent state from being shared across tests when test isolation
|
||||
* is enabled. You shouldn't need to use this command unless you're using it
|
||||
* to clear localStorage inside a single test or test isolation is disabled.
|
||||
*
|
||||
* @see https://on.cypress.io/clearalllocalstorage
|
||||
*/
|
||||
clearAllLocalStorage(options?: Partial<Loggable>): Chainable<null>
|
||||
@@ -941,9 +966,11 @@ declare namespace Cypress {
|
||||
|
||||
/**
|
||||
* Clear data in local storage for the current origin.
|
||||
* Cypress automatically runs this command before each test to prevent state from being
|
||||
* shared across tests. You shouldn't need to use this command unless you're using it
|
||||
* to clear localStorage inside a single test. Yields `localStorage` object.
|
||||
*
|
||||
* Cypress automatically clears all local storage _before_ each test to
|
||||
* prevent state from being shared across tests when test isolation
|
||||
* is enabled. You shouldn't need to use this command unless you're using it
|
||||
* to clear localStorage inside a single test or test isolation is disabled.
|
||||
*
|
||||
* @see https://on.cypress.io/clearlocalstorage
|
||||
* @param {string} [key] - name of a particular item to remove (optional).
|
||||
@@ -1395,19 +1422,26 @@ declare namespace Cypress {
|
||||
get<S = any>(alias: string, options?: Partial<Loggable & Timeoutable & Withinable & Shadow>): Chainable<S>
|
||||
|
||||
/**
|
||||
* Get a browser cookie by its name for the current hostname or for the domain specified.
|
||||
* Get a browser cookie by its name.
|
||||
*
|
||||
* @see https://on.cypress.io/getcookie
|
||||
*/
|
||||
getCookie(name: string, options?: CookieOptions): Chainable<Cookie | null>
|
||||
|
||||
/**
|
||||
* Get all of the browser cookies for the current hostname or for the domain specified.
|
||||
* Get browser cookies for a domain.
|
||||
*
|
||||
* @see https://on.cypress.io/getcookies
|
||||
*/
|
||||
getCookies(options?: CookieOptions): Chainable<Cookie[]>
|
||||
|
||||
/**
|
||||
* Get all browser cookies.
|
||||
*
|
||||
* @see https://on.cypress.io/getallcookies
|
||||
*/
|
||||
getAllCookies(options?: Partial<Loggable & Timeoutable>): Chainable<Cookie[]>
|
||||
|
||||
/**
|
||||
* Navigate back or forward to the previous or next URL in the browser's history.
|
||||
*
|
||||
|
||||
@@ -1020,6 +1020,19 @@ namespace CypressGetCookiesTests {
|
||||
cy.getCookies({ domain: false }) // $ExpectError
|
||||
}
|
||||
|
||||
namespace CypressGetAllCookiesTests {
|
||||
cy.getAllCookies().then((cookies) => {
|
||||
cookies // $ExpectType Cookie[]
|
||||
})
|
||||
cy.getAllCookies({ log: true })
|
||||
cy.getAllCookies({ timeout: 10 })
|
||||
cy.getAllCookies({ log: true, timeout: 10 })
|
||||
|
||||
cy.getAllCookies({ log: 'true' }) // $ExpectError
|
||||
cy.getAllCookies({ timeout: '10' }) // $ExpectError
|
||||
cy.getAllCookies({ other: true }) // $ExpectError
|
||||
}
|
||||
|
||||
namespace CypressGetCookieTests {
|
||||
cy.getCookie('name').then((cookie) => {
|
||||
cookie // $ExpectType Cookie | null
|
||||
@@ -1085,6 +1098,19 @@ namespace CypressClearCookiesTests {
|
||||
cy.clearCookies({ domain: false }) // $ExpectError
|
||||
}
|
||||
|
||||
namespace CypressClearAllCookiesTests {
|
||||
cy.clearAllCookies().then((cookies) => {
|
||||
cookies // $ExpectType null
|
||||
})
|
||||
cy.clearAllCookies({ log: true })
|
||||
cy.clearAllCookies({ timeout: 10 })
|
||||
cy.clearAllCookies({ log: true, timeout: 10 })
|
||||
|
||||
cy.clearAllCookies({ log: 'true' }) // $ExpectError
|
||||
cy.clearAllCookies({ timeout: '10' }) // $ExpectError
|
||||
cy.clearAllCookies({ other: true }) // $ExpectError
|
||||
}
|
||||
|
||||
namespace CypressLocalStorageTests {
|
||||
cy.getAllLocalStorage().then((result) => {
|
||||
result // $ExpectType StorageByOrigin
|
||||
|
||||
@@ -130,6 +130,54 @@ describe('src/cy/commands/cookies - no stub', () => {
|
||||
})
|
||||
})
|
||||
|
||||
context('#getAllCookies', () => {
|
||||
it('returns cookies from all domains', () => {
|
||||
cy.visit('http://barbaz.com:3500/fixtures/generic.html')
|
||||
setCookies()
|
||||
|
||||
cy.getAllCookies().then((cookies) => {
|
||||
expect(cookies).to.have.length(8)
|
||||
|
||||
const sortedCookies = Cypress._.sortBy(cookies, 'name').map((cookie) => `${cookie.name}=${cookie.value}`)
|
||||
|
||||
expect(sortedCookies).to.deep.equal([
|
||||
'key1=value1',
|
||||
'key2=value2',
|
||||
'key3=value3',
|
||||
'key4=value4',
|
||||
'key5=value5',
|
||||
'key6=value6',
|
||||
'key7=value7',
|
||||
'key8=value8',
|
||||
])
|
||||
})
|
||||
|
||||
// webkit does not support cy.origin()
|
||||
if (isWebkit) return
|
||||
|
||||
cy.origin('http://foobar.com:3500', () => {
|
||||
cy.visit('http://foobar.com:3500/fixtures/generic.html')
|
||||
|
||||
cy.getAllCookies().then((cookies) => {
|
||||
expect(cookies).to.have.length(8)
|
||||
|
||||
const sortedCookies = Cypress._.sortBy(cookies, 'name').map((cookie) => `${cookie.name}=${cookie.value}`)
|
||||
|
||||
expect(sortedCookies).to.deep.equal([
|
||||
'key1=value1',
|
||||
'key2=value2',
|
||||
'key3=value3',
|
||||
'key4=value4',
|
||||
'key5=value5',
|
||||
'key6=value6',
|
||||
'key7=value7',
|
||||
'key8=value8',
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
context('#getCookie', () => {
|
||||
const setCookies = () => {
|
||||
cy.log('set cookies')
|
||||
@@ -378,6 +426,36 @@ describe('src/cy/commands/cookies - no stub', () => {
|
||||
})
|
||||
})
|
||||
|
||||
context('#clearAllCookies', () => {
|
||||
it('clears cookies from all domains', () => {
|
||||
cy.visit('http://barbaz.com:3500/fixtures/generic.html')
|
||||
setCookies()
|
||||
cy.clearAllCookies()
|
||||
|
||||
cy.getAllCookies().its('length').should('equal', 0)
|
||||
|
||||
// webkit does not support cy.origin()
|
||||
if (isWebkit) return
|
||||
|
||||
cy.origin('http://foobar.com:3500', () => {
|
||||
cy.visit('http://foobar.com:3500/fixtures/generic.html')
|
||||
// put back cookies removed above
|
||||
cy.setCookie('key1', 'value1', { domain: 'www.foobar.com', log: false })
|
||||
cy.setCookie('key2', 'value2', { domain: 'foobar.com', log: false })
|
||||
cy.setCookie('key3', 'value3', { domain: 'www.barbaz.com', log: false })
|
||||
cy.setCookie('key4', 'value4', { domain: '.www.barbaz.com', log: false })
|
||||
cy.setCookie('key5', 'value5', { domain: 'barbaz.com', log: false })
|
||||
cy.setCookie('key6', 'value6', { domain: '.barbaz.com', log: false })
|
||||
cy.setCookie('key7', 'value7', { domain: 'www2.barbaz.com', log: false })
|
||||
cy.setCookie('key8', 'value8', { domain: 'www2.foobar.com', log: false })
|
||||
|
||||
cy.clearAllCookies()
|
||||
|
||||
cy.getAllCookies().its('length').should('equal', 0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
context('#clearCookie', () => {
|
||||
const setCookies = () => {
|
||||
cy.log('set cookies')
|
||||
@@ -717,6 +795,159 @@ describe('src/cy/commands/cookies', () => {
|
||||
})
|
||||
})
|
||||
|
||||
context('#getAllCookies', () => {
|
||||
it('returns array of cookies', () => {
|
||||
Cypress.automation.withArgs('get:cookies').resolves([])
|
||||
|
||||
cy.getAllCookies().should('deep.eq', []).then(() => {
|
||||
expect(Cypress.automation).to.be.calledWith('get:cookies')
|
||||
})
|
||||
})
|
||||
|
||||
describe('timeout', () => {
|
||||
it('sets timeout to Cypress.config(responseTimeout)', { responseTimeout: 2500 }, () => {
|
||||
Cypress.automation.resolves([])
|
||||
|
||||
const timeout = cy.spy(Promise.prototype, 'timeout')
|
||||
|
||||
cy.getAllCookies().then(() => {
|
||||
expect(timeout).to.be.calledWith(2500)
|
||||
})
|
||||
})
|
||||
|
||||
it('can override timeout', () => {
|
||||
Cypress.automation.resolves([])
|
||||
|
||||
const timeout = cy.spy(Promise.prototype, 'timeout')
|
||||
|
||||
cy.getAllCookies({ timeout: 1000 }).then(() => {
|
||||
expect(timeout).to.be.calledWith(1000)
|
||||
})
|
||||
})
|
||||
|
||||
it('clears the current timeout and restores after success', () => {
|
||||
Cypress.automation.resolves([])
|
||||
|
||||
cy.timeout(100)
|
||||
|
||||
cy.spy(cy, 'clearTimeout')
|
||||
|
||||
cy.getAllCookies().then(() => {
|
||||
expect(cy.clearTimeout).to.be.calledWith('get:cookies')
|
||||
|
||||
// restores the timeout afterwards
|
||||
expect(cy.timeout()).to.eq(100)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('errors', { defaultCommandTimeout: 50 }, () => {
|
||||
beforeEach(function () {
|
||||
this.logs = []
|
||||
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (attrs.name === 'getAllCookies') {
|
||||
this.lastLog = log
|
||||
this.logs.push(log)
|
||||
}
|
||||
})
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
it('logs once on error', function (done) {
|
||||
const error = new Error('some err message')
|
||||
|
||||
error.name = 'foo'
|
||||
error.stack = 'stack'
|
||||
|
||||
Cypress.automation.rejects(error)
|
||||
|
||||
cy.on('fail', () => {
|
||||
const { lastLog } = this
|
||||
|
||||
assertLogLength(this.logs, 1)
|
||||
expect(lastLog.get('error').message).to.contain(`\`cy.getAllCookies()\` had an unexpected error reading cookies from ${Cypress.browser.displayName}.`)
|
||||
expect(lastLog.get('error').message).to.contain('some err message')
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.getAllCookies()
|
||||
})
|
||||
|
||||
it('throws after timing out', function (done) {
|
||||
Cypress.automation.resolves(Promise.delay(1000))
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
const { lastLog } = this
|
||||
|
||||
assertLogLength(this.logs, 1)
|
||||
expect(lastLog.get('error')).to.eq(err)
|
||||
expect(lastLog.get('state')).to.eq('failed')
|
||||
expect(lastLog.get('name')).to.eq('getAllCookies')
|
||||
expect(lastLog.get('message')).to.eq('')
|
||||
expect(err.message).to.eq('`cy.getAllCookies()` timed out waiting `50ms` to complete.')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/getallcookies')
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.getAllCookies({ timeout: 50 })
|
||||
})
|
||||
})
|
||||
|
||||
describe('.log', () => {
|
||||
beforeEach(function () {
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (attrs.name === 'getCookies') {
|
||||
this.lastLog = log
|
||||
}
|
||||
})
|
||||
|
||||
Cypress.automation
|
||||
.withArgs('get:cookies', { domain: 'localhost' })
|
||||
.resolves([
|
||||
{ name: 'foo', value: 'bar', domain: 'localhost', path: '/', secure: true, httpOnly: false, hostOnly: false },
|
||||
])
|
||||
})
|
||||
|
||||
it('can turn off logging', () => {
|
||||
cy.getCookies({ log: false }).then(function () {
|
||||
expect(this.lastLog).to.be.undefined
|
||||
})
|
||||
})
|
||||
|
||||
it('ends immediately', () => {
|
||||
cy.getCookies().then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('ended')).to.be.true
|
||||
expect(lastLog.get('state')).to.eq('passed')
|
||||
})
|
||||
})
|
||||
|
||||
it('snapshots immediately', () => {
|
||||
cy.getCookies().then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('snapshots').length).to.eq(1)
|
||||
expect(lastLog.get('snapshots')[0]).to.be.an('object')
|
||||
})
|
||||
})
|
||||
|
||||
it('#consoleProps', () => {
|
||||
cy.getCookies().then(function (cookies) {
|
||||
expect(cookies).to.deep.eq([{ name: 'foo', value: 'bar', domain: 'localhost', path: '/', secure: true, httpOnly: false }])
|
||||
const c = this.lastLog.invoke('consoleProps')
|
||||
|
||||
expect(c['Yielded']).to.deep.eq(cookies)
|
||||
expect(c['Num Cookies']).to.eq(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
context('#getCookie', () => {
|
||||
it('returns single cookie by name', () => {
|
||||
Cypress.automation.withArgs('get:cookie').resolves({
|
||||
@@ -1495,9 +1726,9 @@ describe('src/cy/commands/cookies', () => {
|
||||
Cypress.automation
|
||||
.withArgs('get:cookies')
|
||||
.resolves([
|
||||
{ name: 'foo' },
|
||||
{ name: 'bar' },
|
||||
{ name: 'baz' },
|
||||
{ name: 'foo', domain: 'localhost' },
|
||||
{ name: 'bar', domain: 'localhost' },
|
||||
{ name: 'baz', domain: 'localhost' },
|
||||
])
|
||||
.withArgs('clear:cookies', [
|
||||
{ name: 'foo', domain: 'localhost' },
|
||||
@@ -1676,7 +1907,7 @@ describe('src/cy/commands/cookies', () => {
|
||||
|
||||
Cypress.automation
|
||||
.withArgs('get:cookies', { domain: 'localhost' })
|
||||
.resolves([{ name: 'foo' }])
|
||||
.resolves([{ name: 'foo', domain: 'localhost' }])
|
||||
.withArgs('clear:cookies', [{ name: 'foo', domain: 'localhost' }])
|
||||
.resolves([
|
||||
{ name: 'foo' },
|
||||
@@ -1754,7 +1985,7 @@ describe('src/cy/commands/cookies', () => {
|
||||
|
||||
Cypress.automation
|
||||
.withArgs('get:cookies', { domain: 'localhost' })
|
||||
.resolves([{ name: 'foo' }])
|
||||
.resolves([{ name: 'foo', domain: 'localhost' }])
|
||||
.withArgs('clear:cookies', [{ name: 'foo', domain: 'localhost' }])
|
||||
.resolves([])
|
||||
})
|
||||
@@ -1771,4 +2002,286 @@ describe('src/cy/commands/cookies', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
context('#clearAllCookies', () => {
|
||||
it('returns null', () => {
|
||||
Cypress.automation.withArgs('get:cookies').resolves([])
|
||||
|
||||
cy.clearAllCookies().should('be.null')
|
||||
})
|
||||
|
||||
it('does not call \'clear:cookies\' when no cookies were returned', () => {
|
||||
Cypress.automation.withArgs('get:cookies').resolves([])
|
||||
|
||||
cy.clearAllCookies().then(() => {
|
||||
expect(Cypress.automation).not.to.be.calledWith(
|
||||
'clear:cookies',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('calls \'clear:cookies\' with all cookies', () => {
|
||||
Cypress.automation
|
||||
.withArgs('get:cookies')
|
||||
.resolves([
|
||||
{ name: 'foo', domain: 'localhost' },
|
||||
{ name: 'bar', domain: 'bar.com' },
|
||||
{ name: 'qux', domain: 'qux.com' },
|
||||
])
|
||||
.withArgs('clear:cookies', [
|
||||
{ name: 'foo', domain: 'localhost' },
|
||||
{ name: 'bar', domain: 'bar.com' },
|
||||
{ name: 'qux', domain: 'qux.com' },
|
||||
])
|
||||
.resolves([
|
||||
{ name: 'foo', domain: 'localhost' },
|
||||
{ name: 'bar', domain: 'bar.com' },
|
||||
{ name: 'qux', domain: 'qux.com' },
|
||||
])
|
||||
|
||||
cy
|
||||
.clearAllCookies().should('be.null').then(() => {
|
||||
expect(Cypress.automation).to.be.calledWith(
|
||||
'clear:cookies', [
|
||||
{ name: 'foo', domain: 'localhost' },
|
||||
{ name: 'bar', domain: 'bar.com' },
|
||||
{ name: 'qux', domain: 'qux.com' },
|
||||
],
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('timeout', () => {
|
||||
beforeEach(() => {
|
||||
Cypress.automation
|
||||
.withArgs('get:cookies')
|
||||
.resolves([{}])
|
||||
.withArgs('clear:cookies')
|
||||
.resolves({})
|
||||
})
|
||||
|
||||
it('sets timeout to Cypress.config(responseTimeout)', {
|
||||
responseTimeout: 2500,
|
||||
}, () => {
|
||||
Cypress.automation.resolves([])
|
||||
|
||||
const timeout = cy.spy(Promise.prototype, 'timeout')
|
||||
|
||||
cy.clearAllCookies().then(() => {
|
||||
expect(timeout).to.be.calledWith(2500)
|
||||
})
|
||||
})
|
||||
|
||||
it('can override timeout', () => {
|
||||
Cypress.automation.resolves([])
|
||||
|
||||
const timeout = cy.spy(Promise.prototype, 'timeout')
|
||||
|
||||
cy.clearAllCookies({ timeout: 1000 }).then(() => {
|
||||
expect(timeout).to.be.calledWith(1000)
|
||||
})
|
||||
})
|
||||
|
||||
it('clears the current timeout and restores after success', () => {
|
||||
cy.timeout(100)
|
||||
|
||||
cy.spy(cy, 'clearTimeout')
|
||||
|
||||
cy.clearAllCookies().then(() => {
|
||||
expect(cy.clearTimeout).to.be.calledWith('get:cookies')
|
||||
expect(cy.clearTimeout).to.be.calledWith('clear:cookies')
|
||||
|
||||
// restores the timeout afterwards
|
||||
expect(cy.timeout()).to.eq(100)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('errors', { defaultCommandTimeout: 100 }, () => {
|
||||
beforeEach(function () {
|
||||
this.logs = []
|
||||
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (attrs.name === 'clearAllCookies') {
|
||||
this.lastLog = log
|
||||
this.logs.push(log)
|
||||
}
|
||||
})
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
it('logs once on \'get:cookies\' error', function (done) {
|
||||
const error = new Error('some err message')
|
||||
|
||||
error.name = 'foo'
|
||||
error.stack = 'some err message\n at fn (foo.js:1:1)'
|
||||
|
||||
Cypress.automation.rejects(error)
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
const { lastLog } = this
|
||||
|
||||
assertLogLength(this.logs, 1)
|
||||
expect(lastLog.get('error').message).to.contain(`\`cy.clearAllCookies()\` had an unexpected error clearing cookies in ${Cypress.browser.displayName}.`)
|
||||
expect(lastLog.get('error').message).to.contain('some err message')
|
||||
expect(lastLog.get('error')).to.eq(err)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.clearAllCookies()
|
||||
})
|
||||
|
||||
it('throws after timing out', function (done) {
|
||||
Cypress.automation.resolves([{ name: 'foo' }])
|
||||
Cypress.automation.withArgs('clear:cookies').resolves(Promise.delay(1000))
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
const { lastLog } = this
|
||||
|
||||
assertLogLength(this.logs, 1)
|
||||
expect(lastLog.get('error')).to.eq(err)
|
||||
expect(lastLog.get('state')).to.eq('failed')
|
||||
expect(lastLog.get('name')).to.eq('clearAllCookies')
|
||||
expect(lastLog.get('message')).to.eq('')
|
||||
expect(err.message).to.eq('`cy.clearAllCookies()` timed out waiting `50ms` to complete.')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/clearallcookies')
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.clearAllCookies({ timeout: 50 })
|
||||
})
|
||||
|
||||
it('logs once on \'clear:cookies\' error', function (done) {
|
||||
Cypress.automation.withArgs('get:cookies').resolves([
|
||||
{ name: 'foo' }, { name: 'bar' },
|
||||
])
|
||||
|
||||
const error = new Error('some err message')
|
||||
|
||||
error.name = 'foo'
|
||||
error.stack = 'stack'
|
||||
|
||||
Cypress.automation.withArgs('clear:cookies').rejects(error)
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
const { lastLog } = this
|
||||
|
||||
assertLogLength(this.logs, 1)
|
||||
expect(lastLog.get('error').message).to.contain(`\`cy.clearAllCookies()\` had an unexpected error clearing cookies in ${Cypress.browser.displayName}.`)
|
||||
expect(lastLog.get('error').message).to.contain('some err message')
|
||||
expect(lastLog.get('error')).to.eq(err)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.clearAllCookies()
|
||||
})
|
||||
})
|
||||
|
||||
describe('.log', () => {
|
||||
beforeEach(function () {
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (attrs.name === 'clearAllCookies') {
|
||||
this.lastLog = log
|
||||
}
|
||||
})
|
||||
|
||||
Cypress.automation
|
||||
.withArgs('get:cookies', {})
|
||||
.resolves([{ name: 'foo', domain: 'localhost' }])
|
||||
.withArgs('clear:cookies', [{ name: 'foo', domain: 'localhost' }])
|
||||
.resolves([
|
||||
{ name: 'foo' },
|
||||
])
|
||||
})
|
||||
|
||||
it('can turn off logging', () => {
|
||||
cy.clearAllCookies({ log: false }).then(function () {
|
||||
expect(this.log).to.be.undefined
|
||||
})
|
||||
})
|
||||
|
||||
it('ends immediately', () => {
|
||||
cy.clearAllCookies().then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('ended')).to.be.true
|
||||
expect(lastLog.get('state')).to.eq('passed')
|
||||
})
|
||||
})
|
||||
|
||||
it('snapshots immediately', () => {
|
||||
cy.clearAllCookies().then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('snapshots').length).to.eq(1)
|
||||
expect(lastLog.get('snapshots')[0]).to.be.an('object')
|
||||
})
|
||||
})
|
||||
|
||||
it('#consoleProps', () => {
|
||||
cy.clearAllCookies().then(function (cookies) {
|
||||
expect(cookies).to.be.null
|
||||
const c = this.lastLog.invoke('consoleProps')
|
||||
|
||||
expect(c['Yielded']).to.eq('null')
|
||||
expect(c['Cleared Cookies']).to.deep.eq([{ name: 'foo' }])
|
||||
expect(c['Num Cookies']).to.eq(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('.log with no cookies returned', () => {
|
||||
beforeEach(function () {
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (attrs.name === 'clearAllCookies') {
|
||||
this.lastLog = log
|
||||
}
|
||||
})
|
||||
|
||||
Cypress.automation
|
||||
.withArgs('get:cookies')
|
||||
.resolves([])
|
||||
})
|
||||
|
||||
it('#consoleProps', () => {
|
||||
cy.clearAllCookies().then(function (cookies) {
|
||||
expect(cookies).to.be.null
|
||||
const c = this.lastLog.invoke('consoleProps')
|
||||
|
||||
expect(c['Yielded']).to.eq('null')
|
||||
expect(c['Cleared Cookies']).to.be.undefined
|
||||
expect(c['Note']).to.eq('No cookies were found or removed.')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('.log when no cookies were cleared', () => {
|
||||
beforeEach(function () {
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (attrs.name === 'clearAllCookies') {
|
||||
this.lastLog = log
|
||||
}
|
||||
})
|
||||
|
||||
Cypress.automation
|
||||
.withArgs('get:cookies', {})
|
||||
.resolves([])
|
||||
})
|
||||
|
||||
it('#consoleProps', () => {
|
||||
cy.clearAllCookies().then(function (cookies) {
|
||||
expect(cookies).to.be.null
|
||||
const c = this.lastLog.invoke('consoleProps')
|
||||
|
||||
expect(c['Yielded']).to.eq('null')
|
||||
expect(c['Cleared Cookies']).to.be.undefined
|
||||
expect(c['Note']).to.eq('No cookies were found or removed.')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -220,6 +220,7 @@ it('verifies number of cy commands', () => {
|
||||
'children', 'eq', 'closest', 'first', 'last', 'next', 'nextAll', 'nextUntil', 'parent', 'parents', 'parentsUntil', 'prev',
|
||||
'prevAll', 'prevUntil', 'siblings', 'wait', 'title', 'window', 'document', 'viewport', 'server', 'route', 'intercept', 'origin',
|
||||
'mount', 'as', 'root', 'getAllLocalStorage', 'clearAllLocalStorage', 'getAllSessionStorage', 'clearAllSessionStorage',
|
||||
'getAllCookies', 'clearAllCookies',
|
||||
]
|
||||
const addedCommands = Cypress._.difference(actualCommands, expectedCommands)
|
||||
const removedCommands = Cypress._.difference(expectedCommands, actualCommands)
|
||||
|
||||
@@ -3,15 +3,12 @@ import Promise from 'bluebird'
|
||||
|
||||
import $utils from '../../cypress/utils'
|
||||
import $errUtils from '../../cypress/error_utils'
|
||||
import type { Log } from '../../cypress/log'
|
||||
|
||||
// TODO: add hostOnly to COOKIE_PROPS
|
||||
// https://github.com/cypress-io/cypress/issues/363
|
||||
// https://github.com/cypress-io/cypress/issues/17527
|
||||
const COOKIE_PROPS = 'name value path secure httpOnly expiry domain sameSite'.split(' ')
|
||||
|
||||
const commandNameRe = /(:)(\w)/
|
||||
|
||||
function pickCookieProps (cookie) {
|
||||
if (!cookie) return cookie
|
||||
|
||||
@@ -22,12 +19,6 @@ function pickCookieProps (cookie) {
|
||||
return _.pick(cookie, COOKIE_PROPS)
|
||||
}
|
||||
|
||||
const getCommandFromEvent = (event) => {
|
||||
return event.replace(commandNameRe, (match, p1, p2) => {
|
||||
return p2.toUpperCase()
|
||||
})
|
||||
}
|
||||
|
||||
// from https://developer.chrome.com/extensions/cookies#type-SameSiteStatus
|
||||
// note that `unspecified` is purposely omitted - Firefox and Chrome set
|
||||
// different defaults, and Firefox lacks support for `unspecified`, so
|
||||
@@ -35,7 +26,7 @@ const getCommandFromEvent = (event) => {
|
||||
// @see https://bugzilla.mozilla.org/show_bug.cgi?id=1624668
|
||||
const VALID_SAMESITE_VALUES = ['no_restriction', 'lax', 'strict']
|
||||
|
||||
const normalizeSameSite = (sameSite) => {
|
||||
function normalizeSameSite (sameSite?: string) {
|
||||
if (_.isUndefined(sameSite)) {
|
||||
return sameSite
|
||||
}
|
||||
@@ -56,12 +47,13 @@ const normalizeSameSite = (sameSite) => {
|
||||
function cookieValidatesHostPrefix (options) {
|
||||
return options.secure === false || (options.path && options.path !== '/')
|
||||
}
|
||||
|
||||
function cookieValidatesSecurePrefix (options) {
|
||||
return options.secure === false
|
||||
}
|
||||
|
||||
function validateDomainOption (domain: any, commandName: string, log: Log | undefined) {
|
||||
if (domain !== undefined && domain !== null && !_.isString(domain)) {
|
||||
function validateDomainOption (domain: any, commandName: string, log: Cypress.Log | undefined) {
|
||||
if (domain !== undefined && typeof domain !== 'string') {
|
||||
$errUtils.throwErrByPath('cookies.invalid_domain', {
|
||||
onFail: log,
|
||||
args: {
|
||||
@@ -72,33 +64,67 @@ function validateDomainOption (domain: any, commandName: string, log: Log | unde
|
||||
}
|
||||
}
|
||||
|
||||
export default function (Commands, Cypress, cy, state, config) {
|
||||
const getDefaultDomain = () => {
|
||||
const hostname = state('window')?.location.hostname
|
||||
interface AutomationEventsAndOptions {
|
||||
'get:cookie': {
|
||||
domain: string
|
||||
name: string
|
||||
}
|
||||
'get:cookies': {
|
||||
domain?: string
|
||||
}
|
||||
'get:all:cookies': {}
|
||||
'set:cookie': {
|
||||
domain: string
|
||||
expiry: number
|
||||
httpOnly: boolean
|
||||
path: string
|
||||
secure: boolean
|
||||
}
|
||||
'clear:cookie': {
|
||||
domain: string
|
||||
name: string
|
||||
}
|
||||
'clear:cookies': Cypress.Cookie[]
|
||||
}
|
||||
|
||||
type CommandName = 'getCookie' | 'getCookies' | 'getAllCookies' | 'setCookie' | 'clearCookie' | 'clearCookies' | 'clearAllCookies'
|
||||
|
||||
interface AutomateOptions<T extends keyof AutomationEventsAndOptions> {
|
||||
event: T
|
||||
options: AutomationEventsAndOptions[T]
|
||||
commandName: CommandName
|
||||
log?: Cypress.Log
|
||||
timeout: number
|
||||
}
|
||||
|
||||
interface GetAndClearOptions {
|
||||
commandName: CommandName
|
||||
log?: Cypress.Log
|
||||
options: AutomationEventsAndOptions['get:cookies']
|
||||
timeout: number
|
||||
}
|
||||
|
||||
export default function (Commands, Cypress: InternalCypress.Cypress, cy, state, config) {
|
||||
function getDefaultDomain () {
|
||||
const win = state('window') as Window | undefined
|
||||
const hostname = win?.location.hostname
|
||||
|
||||
// if hostname is undefined, the AUT is on about:blank, so use the
|
||||
// spec frame's hostname instead
|
||||
return hostname || window.location.hostname
|
||||
}
|
||||
|
||||
const mergeDefaults = function (obj) {
|
||||
// set the default domain to be the AUT hostname
|
||||
const merge = (o) => {
|
||||
return _.defaults(o, { domain: getDefaultDomain() })
|
||||
}
|
||||
|
||||
if (_.isArray(obj)) {
|
||||
return _.map(obj, merge)
|
||||
}
|
||||
|
||||
return merge(obj)
|
||||
}
|
||||
|
||||
const automateCookies = function (event, obj = {}, log, timeout) {
|
||||
function automateCookies<T extends keyof AutomationEventsAndOptions> ({
|
||||
event,
|
||||
options,
|
||||
commandName,
|
||||
log,
|
||||
timeout,
|
||||
}: AutomateOptions<T>) {
|
||||
const automate = () => {
|
||||
return Cypress.automation(event, mergeDefaults(obj))
|
||||
return Cypress.automation(event, options)
|
||||
.catch((err) => {
|
||||
return $errUtils.throwErr(err, { onFail: log })
|
||||
$errUtils.throwErr(err, { onFail: log })
|
||||
})
|
||||
}
|
||||
|
||||
@@ -116,27 +142,39 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
return $errUtils.throwErrByPath('cookies.timed_out', {
|
||||
onFail: log,
|
||||
args: {
|
||||
cmd: getCommandFromEvent(event),
|
||||
cmd: commandName,
|
||||
timeout,
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const getAndClear = (log?, timeout?, options = {}) => {
|
||||
return automateCookies('get:cookies', options, log, timeout)
|
||||
.then((resp) => {
|
||||
const getAndClear = ({ commandName, log, options, timeout }: GetAndClearOptions) => {
|
||||
return automateCookies({
|
||||
event: 'get:cookies',
|
||||
commandName,
|
||||
options,
|
||||
log,
|
||||
timeout,
|
||||
})
|
||||
.then((cookies: Cypress.Cookie[]) => {
|
||||
// bail early if we got no cookies!
|
||||
if (resp && (resp.length === 0)) {
|
||||
return resp
|
||||
if (cookies && cookies.length === 0) {
|
||||
return cookies
|
||||
}
|
||||
|
||||
return automateCookies('clear:cookies', resp, log, timeout)
|
||||
return automateCookies({
|
||||
event: 'clear:cookies',
|
||||
commandName,
|
||||
options: cookies,
|
||||
log,
|
||||
timeout,
|
||||
})
|
||||
})
|
||||
.then(pickCookieProps)
|
||||
}
|
||||
|
||||
const handleBackendError = (command, action, onFail) => {
|
||||
const handleBackendError = (command: CommandName, action: string, onFail?: Cypress.Log) => {
|
||||
return (err) => {
|
||||
if (!_.includes(err.stack, err.message)) {
|
||||
err.stack = `${err.message}\n${err.stack}`
|
||||
@@ -165,7 +203,7 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
}
|
||||
|
||||
return Commands.addAll({
|
||||
getCookie (name, userOptions: Cypress.CookieOptions = {}) {
|
||||
getCookie (name: string, userOptions: Cypress.CookieOptions = {}) {
|
||||
const options: Cypress.CookieOptions = _.defaults({}, userOptions, {
|
||||
log: true,
|
||||
})
|
||||
@@ -175,7 +213,7 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
options.timeout = options.timeout || config('defaultCommandTimeout')
|
||||
|
||||
let cookie: Cypress.Cookie
|
||||
let log: Log | undefined
|
||||
let log: Cypress.Log | undefined
|
||||
|
||||
if (options.log) {
|
||||
log = Cypress.log({
|
||||
@@ -200,10 +238,22 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
$errUtils.throwErrByPath('getCookie.invalid_argument', { onFail: log })
|
||||
}
|
||||
|
||||
validateDomainOption(options.domain, 'getCookie', log)
|
||||
validateDomainOption(userOptions.domain, 'getCookie', log)
|
||||
|
||||
return cy.retryIfCommandAUTOriginMismatch(() => {
|
||||
return automateCookies('get:cookie', { name, domain: options.domain }, log, responseTimeout)
|
||||
return automateCookies({
|
||||
event: 'get:cookie',
|
||||
commandName: 'getCookie',
|
||||
options: {
|
||||
name,
|
||||
// getDefaultDomain() needs to be called inside
|
||||
// cy.retryIfCommandAUTOriginMismatch() (instead of above
|
||||
// where default options are set) in case it errors
|
||||
domain: options.domain || getDefaultDomain(),
|
||||
},
|
||||
timeout: responseTimeout,
|
||||
log,
|
||||
})
|
||||
.then(pickCookieProps)
|
||||
.tap((result) => {
|
||||
cookie = result
|
||||
@@ -222,7 +272,7 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
options.timeout = options.timeout || config('defaultCommandTimeout')
|
||||
|
||||
let cookies: Cypress.Cookie[] = []
|
||||
let log: Log | undefined
|
||||
let log: Cypress.Log | undefined
|
||||
|
||||
if (options.log) {
|
||||
log = Cypress.log({
|
||||
@@ -241,10 +291,21 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
})
|
||||
}
|
||||
|
||||
validateDomainOption(options.domain, 'getCookies', log)
|
||||
validateDomainOption(userOptions.domain, 'getCookies', log)
|
||||
|
||||
return cy.retryIfCommandAUTOriginMismatch(() => {
|
||||
return automateCookies('get:cookies', _.pick(options, 'domain'), log, responseTimeout)
|
||||
return automateCookies({
|
||||
event: 'get:cookies',
|
||||
options: {
|
||||
// getDefaultDomain() needs to be called inside
|
||||
// cy.retryIfCommandAUTOriginMismatch() (instead of above
|
||||
// where default options are set) in case it errors
|
||||
domain: options.domain || getDefaultDomain(),
|
||||
},
|
||||
commandName: 'getCookies',
|
||||
timeout: responseTimeout,
|
||||
log,
|
||||
})
|
||||
.then(pickCookieProps)
|
||||
.tap((result: Cypress.Cookie[]) => {
|
||||
cookies = result
|
||||
@@ -253,7 +314,47 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
}, options.timeout)
|
||||
},
|
||||
|
||||
setCookie (name, value, userOptions: Partial<Cypress.SetCookieOptions> = {}) {
|
||||
getAllCookies (userOptions: Partial<Cypress.Loggable & Cypress.Timeoutable> = {}) {
|
||||
const options: Cypress.CookieOptions = _.defaults({}, userOptions, {
|
||||
log: true,
|
||||
timeout: config('responseTimeout'),
|
||||
})
|
||||
|
||||
let cookies: Cypress.Cookie[] = []
|
||||
let log: Cypress.Log | undefined
|
||||
|
||||
if (options.log) {
|
||||
log = Cypress.log({
|
||||
message: '',
|
||||
timeout: options.timeout,
|
||||
consoleProps () {
|
||||
const obj = {}
|
||||
|
||||
if (cookies.length) {
|
||||
obj['Yielded'] = cookies
|
||||
obj['Num Cookies'] = cookies.length
|
||||
}
|
||||
|
||||
return obj
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return automateCookies({
|
||||
event: 'get:cookies',
|
||||
commandName: 'getAllCookies',
|
||||
options: {},
|
||||
timeout: options.timeout!,
|
||||
log,
|
||||
})
|
||||
.then(pickCookieProps)
|
||||
.tap((result: Cypress.Cookie[]) => {
|
||||
cookies = result
|
||||
})
|
||||
.catch(handleBackendError('getAllCookies', 'reading cookies from', log))
|
||||
},
|
||||
|
||||
setCookie (name: string, value: string, userOptions: Partial<Cypress.SetCookieOptions> = {}) {
|
||||
const options: Partial<Cypress.SetCookieOptions> = _.defaults({}, userOptions, {
|
||||
path: '/',
|
||||
secure: false,
|
||||
@@ -268,7 +369,7 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
|
||||
const cookie = _.extend(pickCookieProps(options), { name, value })
|
||||
let resultingCookie: Cypress.Cookie
|
||||
let log: Log | undefined
|
||||
let log: Cypress.Log | undefined
|
||||
|
||||
if (options.log) {
|
||||
log = Cypress.log({
|
||||
@@ -321,12 +422,23 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
$errUtils.throwErrByPath('setCookie.host_prefix', { onFail: log })
|
||||
}
|
||||
|
||||
validateDomainOption(options.domain, 'setCookie', log)
|
||||
validateDomainOption(userOptions.domain, 'setCookie', log)
|
||||
|
||||
Cypress.emit('set:cookie', cookie)
|
||||
|
||||
return cy.retryIfCommandAUTOriginMismatch(() => {
|
||||
return automateCookies('set:cookie', cookie, log, responseTimeout)
|
||||
// getDefaultDomain() needs to be called inside
|
||||
// cy.retryIfCommandAUTOriginMismatch() (instead of above
|
||||
// where default options are set) in case it errors
|
||||
cookie.domain = options.domain || getDefaultDomain()
|
||||
|
||||
return automateCookies({
|
||||
event: 'set:cookie',
|
||||
commandName: 'setCookie',
|
||||
options: cookie,
|
||||
timeout: responseTimeout,
|
||||
log,
|
||||
})
|
||||
.then(pickCookieProps)
|
||||
.tap((result) => {
|
||||
resultingCookie = result
|
||||
@@ -334,7 +446,7 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
}, options.timeout)
|
||||
},
|
||||
|
||||
clearCookie (name, userOptions: Cypress.CookieOptions = {}) {
|
||||
clearCookie (name: string, userOptions: Cypress.CookieOptions = {}) {
|
||||
const options: Cypress.CookieOptions = _.defaults({}, userOptions, {
|
||||
log: true,
|
||||
})
|
||||
@@ -344,7 +456,7 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
options.timeout = options.timeout || config('defaultCommandTimeout')
|
||||
|
||||
let cookie: Cypress.Cookie
|
||||
let log: Log | undefined
|
||||
let log: Cypress.Log | undefined
|
||||
|
||||
if (options.log) {
|
||||
log = Cypress.log({
|
||||
@@ -370,13 +482,25 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
$errUtils.throwErrByPath('clearCookie.invalid_argument', { onFail: log })
|
||||
}
|
||||
|
||||
validateDomainOption(options.domain, 'clearCookie', log)
|
||||
validateDomainOption(userOptions.domain, 'clearCookie', log)
|
||||
|
||||
Cypress.emit('clear:cookie', name)
|
||||
|
||||
// TODO: prevent clearing a cypress namespace
|
||||
return cy.retryIfCommandAUTOriginMismatch(() => {
|
||||
return automateCookies('clear:cookie', { name, domain: options.domain }, log, responseTimeout)
|
||||
return automateCookies({
|
||||
event: 'clear:cookie',
|
||||
commandName: 'clearCookie',
|
||||
options: {
|
||||
name,
|
||||
// getDefaultDomain() needs to be called inside
|
||||
// cy.retryIfCommandAUTOriginMismatch() (instead of above
|
||||
// where default options are set) in case it errors
|
||||
domain: options.domain || getDefaultDomain(),
|
||||
},
|
||||
timeout: responseTimeout,
|
||||
log,
|
||||
})
|
||||
.then(pickCookieProps)
|
||||
.then((result) => {
|
||||
cookie = result
|
||||
@@ -398,11 +522,11 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
options.timeout = options.timeout || config('defaultCommandTimeout')
|
||||
|
||||
let cookies: Cypress.Cookie[] = []
|
||||
let log: Log | undefined
|
||||
let log: Cypress.Log | undefined
|
||||
|
||||
if (options.log) {
|
||||
log = Cypress.log({
|
||||
message: userOptions.domain ? { domain: userOptions.domain } : '',
|
||||
message: userOptions.domain ? { domain: userOptions.domain! } : '',
|
||||
timeout: responseTimeout,
|
||||
consoleProps () {
|
||||
const obj = {}
|
||||
@@ -421,24 +545,77 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
})
|
||||
}
|
||||
|
||||
validateDomainOption(options.domain, 'clearCookies', log)
|
||||
validateDomainOption(userOptions.domain, 'clearCookies', log)
|
||||
|
||||
Cypress.emit('clear:cookies')
|
||||
|
||||
return cy.retryIfCommandAUTOriginMismatch(() => {
|
||||
return getAndClear(log, responseTimeout, { domain: options.domain })
|
||||
return getAndClear({
|
||||
log,
|
||||
timeout: responseTimeout,
|
||||
options: {
|
||||
// getDefaultDomain() needs to be called inside
|
||||
// cy.retryIfCommandAUTOriginMismatch() (instead of above
|
||||
// where default options are set) in case it errors
|
||||
domain: options.domain || getDefaultDomain(),
|
||||
},
|
||||
commandName: 'clearCookies',
|
||||
})
|
||||
.then((result) => {
|
||||
cookies = result
|
||||
|
||||
// null out the current subject
|
||||
return null
|
||||
}).catch((err) => {
|
||||
// make sure we always say to clearCookies
|
||||
err.message = err.message.replace('getCookies', 'clearCookies')
|
||||
throw err
|
||||
})
|
||||
.catch(handleBackendError('clearCookies', 'clearing cookies in', log))
|
||||
}, options.timeout)
|
||||
},
|
||||
|
||||
clearAllCookies (userOptions: Partial<Cypress.Loggable & Cypress.Timeoutable>) {
|
||||
const options: Cypress.CookieOptions = _.defaults({}, userOptions, {
|
||||
log: true,
|
||||
timeout: config('responseTimeout'),
|
||||
})
|
||||
|
||||
let cookies: Cypress.Cookie[] = []
|
||||
let log: Cypress.Log | undefined
|
||||
|
||||
if (options.log) {
|
||||
log = Cypress.log({
|
||||
message: '',
|
||||
timeout: options.timeout,
|
||||
consoleProps () {
|
||||
const obj = {}
|
||||
|
||||
obj['Yielded'] = 'null'
|
||||
|
||||
if (cookies.length) {
|
||||
obj['Cleared Cookies'] = cookies
|
||||
obj['Num Cookies'] = cookies.length
|
||||
} else {
|
||||
obj['Note'] = 'No cookies were found or removed.'
|
||||
}
|
||||
|
||||
return obj
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
Cypress.emit('clear:cookies')
|
||||
|
||||
return getAndClear({
|
||||
log,
|
||||
timeout: options.timeout!,
|
||||
options: {},
|
||||
commandName: 'clearAllCookies',
|
||||
})
|
||||
.then((result) => {
|
||||
cookies = result
|
||||
|
||||
// null out the current subject
|
||||
return null
|
||||
})
|
||||
.catch(handleBackendError('clearAllCookies', 'clearing cookies in', log))
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -562,7 +562,7 @@ describe('app/background', () => {
|
||||
])
|
||||
})
|
||||
|
||||
it('returns all cookies that match filter', function (done) {
|
||||
it('returns cookies that match filter', function (done) {
|
||||
this.socket.on('automation:response', (id, obj = {}) => {
|
||||
expect(id).to.eq(123)
|
||||
expect(obj.response).to.deep.eq([{ cookie: '1', domain: 'example.com' }])
|
||||
@@ -572,6 +572,20 @@ describe('app/background', () => {
|
||||
|
||||
this.server.emit('automation:request', 123, 'get:cookies', { domain: 'example.com' })
|
||||
})
|
||||
|
||||
it('returns all cookies if there is no filter', function (done) {
|
||||
this.socket.on('automation:response', (id, obj = {}) => {
|
||||
expect(id).to.eq(123)
|
||||
expect(obj.response).to.deep.eq([
|
||||
{ cookie: '1', domain: 'example.com' },
|
||||
{ cookie: '2', domain: 'www.example.com' },
|
||||
])
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
this.server.emit('automation:request', 123, 'get:cookies', {})
|
||||
})
|
||||
})
|
||||
|
||||
describe('get:cookie', () => {
|
||||
|
||||
@@ -137,11 +137,12 @@ context('lib/browsers/cdp_automation', () => {
|
||||
cookies: [
|
||||
{ name: 'foo', value: 'f', path: '/', domain: 'localhost', secure: true, httpOnly: true, expires: 123 },
|
||||
{ name: 'bar', value: 'b', path: '/', domain: 'localhost', secure: false, httpOnly: false, expires: 456 },
|
||||
{ name: 'qux', value: 'q', path: '/', domain: 'foobar.com', secure: false, httpOnly: false, expires: 789 },
|
||||
],
|
||||
})
|
||||
})
|
||||
|
||||
it('returns all cookies', function () {
|
||||
it('returns cookies that match filter', function () {
|
||||
return this.onRequest('get:cookies', { domain: 'localhost' })
|
||||
.then((resp) => {
|
||||
expect(resp).to.deep.eq([
|
||||
@@ -150,6 +151,17 @@ context('lib/browsers/cdp_automation', () => {
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
it('returns all cookies if there is no filter', function () {
|
||||
return this.onRequest('get:cookies', {})
|
||||
.then((resp) => {
|
||||
expect(resp).to.deep.eq([
|
||||
{ name: 'foo', value: 'f', path: '/', domain: 'localhost', secure: true, httpOnly: true, expirationDate: 123, sameSite: undefined },
|
||||
{ name: 'bar', value: 'b', path: '/', domain: 'localhost', secure: false, httpOnly: false, expirationDate: 456, sameSite: undefined },
|
||||
{ name: 'qux', value: 'q', path: '/', domain: 'foobar.com', secure: false, hostOnly: true, httpOnly: false, expirationDate: 789, sameSite: undefined },
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('get:cookie', () => {
|
||||
|
||||
@@ -276,12 +276,12 @@ describe('cookies', () => {
|
||||
expectedGetCookiesArray = _.reverse(_.sortBy(expectedGetCookiesArray, _.property('name')))
|
||||
|
||||
// sanity check
|
||||
cy.clearCookies({ domain: null })
|
||||
cy.getCookies({ domain: null }).should('have.length', 0)
|
||||
cy.clearAllCookies()
|
||||
cy.getAllCookies().should('have.length', 0)
|
||||
|
||||
cy[cmd](`/setCascadingCookies?n=${n}&a=${altUrl}&b=${Cypress.env('baseUrl')}`)
|
||||
|
||||
cy.getCookies({ domain: null }).then((cookies) => {
|
||||
cy.getAllCookies().then((cookies) => {
|
||||
// reverse them so they'll be in the order they were set
|
||||
cookies = _.reverse(_.sortBy(cookies, _.property('name')))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user