Skip to content

Commit

Permalink
fix: persist registered spec sessions (#23347)
Browse files Browse the repository at this point in the history
  • Loading branch information
emilyrohrbough authored Aug 16, 2022
1 parent 7489561 commit ae5cbb5
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 80 deletions.
81 changes: 49 additions & 32 deletions packages/app/cypress/e2e/runner/sessions.ui.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,51 +131,68 @@ describe('runner/cypress sessions.ui.spec', {
cy.percySnapshot()
})

it('restores saved session', () => {
loadSpec({
projectName: 'session-and-origin-e2e-specs',
filePath: 'session/restores_saved_session.cy.js',
passCount: 2,
describe('restores saved session', () => {
beforeEach(() => {
loadSpec({
projectName: 'session-and-origin-e2e-specs',
filePath: 'session/restores_saved_session.cy.js',
passCount: 5,
failCount: 1,
})
})

cy.get('.test').each(($el) => cy.wrap($el).click())
it('restores session as expected', () => {
cy.get('.test').each(($el) => cy.wrap($el).click())

cy.log('validate new session was created in first test')
cy.get('.test').eq(0).within(() => {
validateSessionsInstrumentPanel(['user1'])
cy.get('.command-name-session').contains('created')
})
cy.log('validate new session was created in first test')
cy.get('.test').eq(0).within(() => {
validateSessionsInstrumentPanel(['user1'])
cy.get('.command-name-session').contains('created')
})

cy.log('validate saved session was used in second test')
cy.get('.test').eq(1).within(() => {
validateSessionsInstrumentPanel(['user1'])
cy.log('validate saved session was used in second test')
cy.get('.test').eq(1).within(() => {
validateSessionsInstrumentPanel(['user1'])

cy.get('.command-name-session')
.within(() => {
cy.get('.command-expander').first().click()
cy.contains('user1')
cy.contains('restored')
cy.get('.command-name-session')
.within(() => {
cy.get('.command-expander').first().click()
cy.contains('user1')
cy.contains('restored')

cy.get('.command-name-Clear-page').should('have.length', 2)
cy.get('.command-name-Clear-page').should('have.length', 2)

cy.contains('Restore saved session')
cy.contains('Restore saved session')

cy.contains('Validate session')
.closest('.command').as('validateSession')
cy.contains('Validate session')
.closest('.command').as('validateSession')

cy.get('@validateSession')
.find('.command-expander')
.should('not.have.class', 'command-expander-is-open')
.click()
cy.get('@validateSession')
.find('.command-expander')
.should('not.have.class', 'command-expander-is-open')
.click()

cy.get('@validateSession')
.find('.command-alias')
.contains('runValidation')
cy.get('@validateSession')
.find('.command-alias')
.contains('runValidation')
})

cy.get('.command-name-session').get('.command-expander').first().click()

cy.get('.command').should('have.length', 2)
})
})

cy.get('.command-name-session').get('.command-expander').first().click()
// https://github.com/cypress-io/cypress/issues/22381
it('ensures sessionid integrity is maintained across tests', () => {
cy.contains('test sessionid integrity is maintained').closest('.runnable').should('have.class', 'runnable-failed')
cy.get('.test').should('have.length', 6)

cy.get('.command').should('have.length', 2)
cy.get('.test').eq(2).should('have.class', 'runnable-passed')
cy.get('.test').eq(3).should('have.class', 'runnable-passed')
cy.get('.test').eq(4).should('have.class', 'runnable-passed')
cy.get('.test').eq(5).should('have.class', 'runnable-failed')
cy.contains('If you want to specify different options, please use a unique name').should('exist')
})
})

Expand Down
4 changes: 2 additions & 2 deletions packages/driver/cypress/e2e/commands/sessions/manager.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ describe('src/cy/commands/sessions/manager.ts', () => {

expect(sessionsManager).to.haveOwnProperty('cy')
expect(sessionsManager).to.haveOwnProperty('Cypress')
expect(sessionsManager).to.haveOwnProperty('currentTestRegisteredSessions')
expect(sessionsManager.currentTestRegisteredSessions).to.be.instanceOf(Map)
expect(sessionsManager).to.haveOwnProperty('registeredSessions')
expect(sessionsManager.registeredSessions).to.be.instanceOf(Map)
})

describe('.setActiveSession()', () => {
Expand Down
23 changes: 12 additions & 11 deletions packages/driver/cypress/e2e/commands/sessions/sessions.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe('cy.session', { retries: 0 }, () => {

it('accepts array as id', () => {
cy.session('session-id', () => {})
cy.session('session-id')
})

it('accepts object as id', () => {
Expand All @@ -35,7 +36,7 @@ describe('cy.session', { retries: 0 }, () => {
const setup = cy.stub().as('setupSession')
const validate = cy.stub().as('validateSession')

cy.session('session-id', setup, { validate })
cy.session('session-id-3rd-arg', setup, { validate })
cy.then(() => {
expect(setup).to.be.calledOnce
expect(validate).to.be.calledOnce
Expand Down Expand Up @@ -236,7 +237,7 @@ describe('cy.session', { retries: 0 }, () => {
setupTestContext()
cy.log('Creating new session with validation to test against')

cy.session('session-1', setup, { validate })
cy.session(`session-${Cypress.state('test').id}`, setup, { validate })
cy.url().should('eq', 'about:blank')
})

Expand Down Expand Up @@ -366,22 +367,22 @@ describe('cy.session', { retries: 0 }, () => {

validate.callsFake(() => false)

cy.session('session-1', setup, { validate })
cy.session(`session-${Cypress.state('test').id}`, setup, { validate })
})
})

describe('restores saved session flow', () => {
before(() => {
setupTestContext()
cy.log('Creating new session for test')
cy.session('session-1', setup)
cy.session(`session-${Cypress.state('test').id}`, setup)
.then(() => {
// reset and only test restored session
resetMocks()
})

cy.log('restore session to test against')
cy.session('session-1', setup)
cy.session(`session-${Cypress.state('test').id}`, setup)
cy.url().should('eq', 'about:blank')
})

Expand Down Expand Up @@ -433,14 +434,14 @@ describe('cy.session', { retries: 0 }, () => {
before(() => {
setupTestContext()
cy.log('Creating new session for test')
cy.session('session-1', setup, { validate })
cy.session(`session-${Cypress.state('test').id}`, setup, { validate })
.then(() => {
// reset and only test restored session
resetMocks()
})

cy.log('restore session to test against')
cy.session('session-1', setup, { validate })
cy.session(`session-${Cypress.state('test').id}`, setup, { validate })
cy.url().should('eq', 'about:blank')
})

Expand Down Expand Up @@ -504,7 +505,7 @@ describe('cy.session', { retries: 0 }, () => {
before(() => {
setupTestContext()
cy.log('Creating new session for test')
cy.session('session-1', setup, { validate })
cy.session(`session-${Cypress.state('test').id}`, setup, { validate })
.then(() => {
// reset and only test restored session
resetMocks()
Expand All @@ -516,7 +517,7 @@ describe('cy.session', { retries: 0 }, () => {
})

cy.log('restore session to test against')
cy.session('session-1', setup, { validate })
cy.session(`session-${Cypress.state('test').id}`, setup, { validate })
cy.url().should('eq', 'about:blank')
})

Expand Down Expand Up @@ -627,7 +628,7 @@ describe('cy.session', { retries: 0 }, () => {
it('fails to recreate session and logs correctly', function (done) {
setupTestContext()
cy.log('Creating new session for test')
cy.session('session-1', setup, { validate })
cy.session(`session-${Cypress.state('test').id}`, setup, { validate })
.then(() => {
// reset and only test restored session
resetMocks()
Expand Down Expand Up @@ -733,7 +734,7 @@ describe('cy.session', { retries: 0 }, () => {
})

cy.log('restore session to test against')
cy.session('session-1', setup, { validate })
cy.session(`session-${Cypress.state('test').id}`, setup, { validate })
})
})
})
Expand Down
12 changes: 5 additions & 7 deletions packages/driver/src/cy/commands/sessions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ export default function (Commands, Cypress, cy) {
Cypress.on('run:start', () => {
Cypress.on('test:before:run:async', () => {
if (Cypress.config('experimentalSessionAndOrigin')) {
sessionsManager.currentTestRegisteredSessions.clear()

const clearPage = Cypress.config('testIsolation') === 'strict' ? navigateAboutBlank(false) : new Cypress.Promise.resolve()

return clearPage
Expand Down Expand Up @@ -92,18 +90,18 @@ export default function (Commands, Cypress, cy) {
}

let existingSession: SessionData = sessionsManager.getActiveSession(id)
const isRegisteredSessionForTest = sessionsManager.currentTestRegisteredSessions.has(id)
const isRegisteredSessionForSpec = sessionsManager.registeredSessions.has(id)

if (!setup) {
if (!existingSession || !isRegisteredSessionForTest) {
if (!existingSession || !isRegisteredSessionForSpec) {
$errUtils.throwErrByPath('sessions.session.not_found', { args: { id } })
}
} else {
const isUniqSessionDefinition = !existingSession || existingSession.setup.toString().trim() !== setup.toString().trim()

if (isUniqSessionDefinition) {
if (isRegisteredSessionForTest) {
$errUtils.throwErrByPath('sessions.session.duplicateId', { args: { id: existingSession.id } })
if (isRegisteredSessionForSpec) {
$errUtils.throwErrByPath('sessions.session.duplicateId', { args: { id } })
}

existingSession = sessions.defineSession({
Expand All @@ -112,7 +110,7 @@ export default function (Commands, Cypress, cy) {
validate: options.validate,
})

sessionsManager.currentTestRegisteredSessions.set(id, true)
sessionsManager.registeredSessions.set(id, true)
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/driver/src/cy/commands/sessions/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const getLogProperties = (displayName) => {
export default class SessionsManager {
Cypress
cy
currentTestRegisteredSessions = new Map()
registeredSessions = new Map()

constructor (Cypress, cy) {
this.Cypress = Cypress
Expand Down
13 changes: 5 additions & 8 deletions system-tests/__snapshots__/session_spec.ts.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,6 @@ exports['e2e sessions / session tests'] = `
can wait for login redirect automatically
✓ t1
can wait for a js redirect with an assertion
✓ t1
same session name, different options, multiple tests
✓ t1
✓ t2
Expand All @@ -107,15 +104,15 @@ exports['e2e sessions / session tests'] = `
✓ clears only secure context data - 2/2
43 passing
42 passing
1 pending
(Results)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Tests: 44
│ Passing: 43
│ Tests: 43
│ Passing: 42
│ Failing: 0 │
│ Pending: 1 │
│ Skipped: 0 │
Expand All @@ -133,9 +130,9 @@ exports['e2e sessions / session tests'] = `
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ session.cy.js XX:XX 44 43 - 1 - │
│ ✔ session.cy.js XX:XX 43 42 - 1 - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! XX:XX 44 43 - 1 -
✔ All specs passed! XX:XX 43 42 - 1 -
`
Expand Down
22 changes: 3 additions & 19 deletions system-tests/projects/e2e/cypress/e2e/session.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ describe('options.validate reruns steps when rejecting', () => {
})

describe('options.validate reruns steps when throwing', () => {
SuiteWithValidateFn('validate_reject', (callCount) => {
SuiteWithValidateFn('validate_throw', (callCount) => {
if (callCount === 2) {
throw new Error('validate error')
}
Expand Down Expand Up @@ -460,22 +460,6 @@ describe('can wait for login redirect automatically', () => {
cy.session('redirect-login', () => {
cy.visit('https://localhost:4466/form')
cy.get('[name="delay"]').type('100{enter}')
// not needed since cypress will pause command queue during the redirect
// cy.url().should('include', '/home')
})

expectCurrentSessionData({
cookies: ['/form', '/home'],
})
})
})

describe('can wait for a js redirect with an assertion', () => {
it('t1', () => {
cy.session('redirect-login', () => {
cy.visit('https://localhost:4466/form')
cy.get('[name="delay"]').type('100{enter}')
// cy.url().should('include', '/home')
})

expectCurrentSessionData({
Expand All @@ -486,7 +470,7 @@ describe('can wait for a js redirect with an assertion', () => {

describe('same session name, different options, multiple tests', () => {
it('t1', () => {
cy.session('bob', () => {
cy.session('bob_1', () => {
localStorage.bob = '1'
})
.then(() => {
Expand All @@ -495,7 +479,7 @@ describe('same session name, different options, multiple tests', () => {
})

it('t2', () => {
cy.session('bob', () => {
cy.session('bob_2', () => {
localStorage.bob = '2'
})
.then(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,26 @@ it('t2', () => {

cy.log('after')
})

// https://github.com/cypress-io/cypress/issues/22381
describe('test sessionid integrity is maintained', () => {
it('use same session 2x and 2nd does not provide setup', () => {
cy.session('session-2', setupFn)
cy.session('session-2')
})

it('restore prev session 2x and 2nd does not provide setup', () => {
cy.session('session-2', setupFn)
cy.session('session-2')
})

it('restore prev session without setup', () => {
cy.session('session-2')
})

it('fails when trying to use existing sessionid with diff args', () => {
cy.session('session-2', () => {
// something else
})
})
})

3 comments on commit ae5cbb5

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on ae5cbb5 Aug 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.6.0/linux-x64/develop-ae5cbb592d0579da51e733853cf5c7da927db89a/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on ae5cbb5 Aug 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux arm64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.6.0/linux-arm64/develop-ae5cbb592d0579da51e733853cf5c7da927db89a/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on ae5cbb5 Aug 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.6.0/win32-x64/develop-ae5cbb592d0579da51e733853cf5c7da927db89a/cypress.tgz

Please sign in to comment.