Skip to content

Commit a5ec234

Browse files
Merge pull request #23904 from cypress-io/cache-sessions
2 parents 238ead3 + 1d47226 commit a5ec234

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+624
-295
lines changed

cli/types/cypress.d.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,22 @@ declare namespace Cypress {
661661
}
662662

663663
interface SessionOptions {
664-
validate?: () => false | void
664+
/**
665+
* Whether or not to persist the session across all specs in the run.
666+
* @default {false}
667+
*/
668+
cacheAcrossSpecs?: boolean,
669+
/**
670+
* Function to run immediately after the session is created and `setup` function runs or
671+
* after a session is restored and the page is cleared. If this returns `false`, throws an
672+
* exception, returns a Promise which resolves to `false` or rejects or contains any failing
673+
* Cypress command, the session is considered invalid.
674+
*
675+
* If validation fails immediately after `setup`, the test will fail.
676+
* If validation fails after restoring a session, `setup` will re-run.
677+
* @default {false}
678+
*/
679+
validate?: () => Promise<false | void> | false | void
665680
}
666681

667682
type CanReturnChainable = void | Chainable | Promise<unknown>
@@ -1080,7 +1095,7 @@ declare namespace Cypress {
10801095
*
10811096
* @see https://on.cypress.io/session
10821097
*/
1083-
session(id: string | object, setup?: SessionOptions['validate'], options?: SessionOptions): Chainable<null>
1098+
session(id: string | object, setup?: () => void, options?: SessionOptions): Chainable<null>
10841099

10851100
/**
10861101
* Get the window.document of the page that is currently active.

packages/app/cypress/e2e/runner/sessions.ui.cy.ts

Lines changed: 69 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { snapshotReporter } from './support/snapshot-reporter'
44
const validateSessionsInstrumentPanel = (sessionIds: Array<string> = []) => {
55
cy.get('.sessions-container')
66
.should('contain', `Sessions (${sessionIds.length})`)
7+
.as('instrument_panel')
78
.click()
89

910
sessionIds.forEach((id) => {
@@ -142,7 +143,11 @@ describe('runner/cypress sessions.ui.spec', {
142143
})
143144

144145
it('restores session as expected', () => {
145-
cy.get('.test').each(($el) => cy.wrap($el).click())
146+
cy.get('.test').each(($el, index) => {
147+
if (index < 5) { // don't click on failed test
148+
cy.wrap($el).click()
149+
}
150+
})
146151

147152
cy.log('validate new session was created in first test')
148153
cy.get('.test').eq(0).within(() => {
@@ -153,7 +158,6 @@ describe('runner/cypress sessions.ui.spec', {
153158
cy.log('validate saved session was used in second test')
154159
cy.get('.test').eq(1).within(() => {
155160
validateSessionsInstrumentPanel(['user1'])
156-
157161
cy.get('.command-name-session')
158162
.within(() => {
159163
cy.get('.command-expander').first().click()
@@ -192,7 +196,7 @@ describe('runner/cypress sessions.ui.spec', {
192196
cy.get('.test').eq(3).should('have.class', 'runnable-passed')
193197
cy.get('.test').eq(4).should('have.class', 'runnable-passed')
194198
cy.get('.test').eq(5).should('have.class', 'runnable-failed')
195-
cy.contains('If you want to specify different options, please use a unique name').should('exist')
199+
cy.contains('This session already exists.').should('exist')
196200
})
197201
})
198202

@@ -323,7 +327,7 @@ describe('runner/cypress sessions.ui.spec', {
323327
passCount: 1,
324328
})
325329

326-
validateSessionsInstrumentPanel(['user1', 'user2'])
330+
validateSessionsInstrumentPanel(['spec_session_1', 'spec_session_2', 'global_session_1'])
327331
// cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435
328332
})
329333
})
@@ -340,50 +344,91 @@ describe('runner/cypress sessions.open_mode.spec', () => {
340344
passCount: 1,
341345
})
342346

343-
cy.get('.command-name-session').should('contain', 'user1')
344-
.find('.reporter-tag').should('contain', 'created')
345-
346-
cy.get('.command-name-session').should('contain', 'user2')
347-
.find('.reporter-tag').should('contain', 'created')
347+
cy.get('.reporter-tag').should('contain', 'created').should('length', 3)
348348
})
349349

350-
it('persists spec sessions when clicking "rerun all tests" button', () => {
350+
it('persists global and spec sessions when clicking "rerun all tests" button', () => {
351351
cy.get('.restart').click()
352352

353353
cy.waitForSpecToFinish({
354354
passCount: 1,
355355
})
356356

357-
cy.get('.command-name-session').should('contain', 'user1')
358-
.find('.reporter-tag').should('contain', 'restored')
359-
360-
cy.get('.command-name-session').should('contain', 'user2')
361-
.find('.reporter-tag').should('contain', 'restored')
357+
cy.get('.reporter-tag').should('contain', 'restored').should('length', 3)
362358
})
363359

364-
it('persists spec sessions on refresh', () => {
360+
it('persists global and spec sessions on refresh', () => {
365361
cy.get('body').type('r')
366362

367363
cy.waitForSpecToFinish({
368364
passCount: 1,
369365
})
370366

371-
cy.get('.command-name-session').should('contain', 'user1')
372-
.find('.reporter-tag').should('contain', 'restored')
373-
374-
cy.get('.command-name-session').should('contain', 'user2')
375-
.find('.reporter-tag').should('contain', 'restored')
367+
cy.get('.reporter-tag').should('contain', 'restored').should('length', 3)
376368
})
377369

378-
it('does not persists spec sessions when selecting a different spec', () => {
370+
it('persists global session and does not persists spec session when selecting a different spec', () => {
379371
cy.get('body').type('f')
380-
cy.get('div[title="new_session.cy.js"]').click()
372+
cy.get('div[title="blank_session.cy.js"]').click()
381373

382374
cy.waitForSpecToFinish({
383375
passCount: 1,
384376
})
385377

386-
cy.get('.command-name-session').should('contain', 'user1')
378+
cy.get('.command-name-session').eq(0).should('contain', 'spec_session')
387379
.find('.reporter-tag').should('contain', 'created')
380+
381+
cy.get('.command-name-session').eq(1).should('contain', 'global_session_1')
382+
.find('.reporter-tag').should('contain', 'restored')
383+
})
384+
385+
it('clears all sessions when selecting "clear all sessions"', () => {
386+
cy.get('body').type('r')
387+
388+
cy.waitForSpecToFinish({
389+
passCount: 1,
390+
})
391+
392+
cy.get('.reporter-tag').should('contain', 'restored').should('length', 3)
393+
394+
cy.contains('Clear All Sessions').click()
395+
396+
cy.contains('Your tests are loading...')
397+
398+
cy.waitForSpecToFinish({
399+
passCount: 1,
400+
})
401+
402+
cy.get('.reporter-tag').should('contain', 'created').should('length', 3)
403+
})
404+
})
405+
406+
describe('global sessions', () => {
407+
beforeEach(() => {
408+
cy.scaffoldProject('session-and-origin-e2e-specs')
409+
cy.openProject('session-and-origin-e2e-specs')
410+
cy.startAppServer('e2e')
411+
cy.visitApp()
412+
413+
cy.get('[data-cy-row="global_sessions.cy.js"]').click()
414+
cy.waitForSpecToFinish({
415+
passCount: 2,
416+
})
417+
})
418+
419+
it('creates global session', () => {
420+
cy.contains('.test', 'creates global session').as('creates_global').click()
421+
cy.get('@creates_global').within(() => {
422+
cy.get('.command-name-session').should('contain', 'global_session_1')
423+
.find('.reporter-tag').should('contain', 'created')
424+
})
425+
})
426+
427+
it('restores global session', () => {
428+
cy.contains('.test', 'restores global session').as('restores_global').click()
429+
cy.get('@restores_global').within(() => {
430+
cy.get('.command-name-session').should('contain', 'global_session_1')
431+
.find('.reporter-tag').should('contain', 'restored')
432+
})
388433
})
389434
})

packages/app/src/runner/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export function getEventManager () {
6767

6868
window.getEventManager = getEventManager
6969

70-
let _autIframeModel: AutIframe
70+
let _autIframeModel: AutIframe | null
7171

7272
/**
7373
* Creates an instance of an AutIframe model which ise used to control

packages/data-context/src/sources/HtmlDataSource.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export class HtmlDataSource {
4242
throw err
4343
}
4444

45-
getPropertiesFromLegacyConfig (cfg: any) {
45+
getPropertiesFromServerConfig (cfg: any = {}) {
4646
const keys = [
4747
'baseUrl',
4848
'browserUrl',
@@ -62,7 +62,7 @@ export class HtmlDataSource {
6262
}
6363

6464
async makeServeConfig () {
65-
const propertiesFromLegacyConfig = this.getPropertiesFromLegacyConfig(this.ctx._apis.projectApi.getConfig() ?? {})
65+
const propertiesFromLegacyConfig = this.getPropertiesFromServerConfig(this.ctx._apis.projectApi.getConfig())
6666

6767
let cfg = { ...propertiesFromLegacyConfig }
6868

packages/driver/cypress/e2e/commands/sessions/manager.cy.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ describe('src/cy/commands/sessions/manager.ts', () => {
2828
'session_1': {
2929
id: 'session_1',
3030
setup: () => {},
31+
cacheAcrossSpecs: false,
3132
hydrated: true,
3233
},
3334
}
@@ -47,11 +48,13 @@ describe('src/cy/commands/sessions/manager.ts', () => {
4748
'session_1': {
4849
id: 'session_1',
4950
setup: () => {},
51+
cacheAcrossSpecs: false,
5052
hydrated: false,
5153
},
5254
'session_2': {
5355
id: 'session_2',
5456
setup: () => {},
57+
cacheAcrossSpecs: false,
5558
hydrated: true,
5659
},
5760
}
@@ -62,6 +65,7 @@ describe('src/cy/commands/sessions/manager.ts', () => {
6265
'session_3': {
6366
id: 'session_3',
6467
setup: () => {},
68+
cacheAcrossSpecs: false,
6569
hydrated: true,
6670
},
6771
}
@@ -96,11 +100,13 @@ describe('src/cy/commands/sessions/manager.ts', () => {
96100
'session_1': {
97101
id: 'session_1',
98102
setup: () => {},
103+
cacheAcrossSpecs: false,
99104
hydrated: false,
100105
},
101106
'session_2': {
102107
id: 'session_2',
103108
setup: () => {},
109+
cacheAcrossSpecs: false,
104110
hydrated: true,
105111
},
106112
}
@@ -135,11 +141,13 @@ describe('src/cy/commands/sessions/manager.ts', () => {
135141
'session_1': {
136142
id: 'session_1',
137143
setup: () => {},
144+
cacheAcrossSpecs: false,
138145
hydrated: false,
139146
},
140147
'session_2': {
141148
id: 'session_2',
142149
setup: () => {},
150+
cacheAcrossSpecs: false,
143151
hydrated: true,
144152
},
145153
}
@@ -236,6 +244,7 @@ describe('src/cy/commands/sessions/manager.ts', () => {
236244
setup,
237245
validate: undefined,
238246
cookies: null,
247+
cacheAcrossSpecs: false,
239248
localStorage: null,
240249
sessionStorage: null,
241250
hydrated: false,

0 commit comments

Comments
 (0)