Skip to content

Commit

Permalink
feat: add warned command state to use for recreated sessions (#24592)
Browse files Browse the repository at this point in the history
Co-authored-by: Bill Glesias <bglesias@gmail.com>
  • Loading branch information
emilyrohrbough and AtofStryker committed Nov 16, 2022
1 parent 206fdd5 commit 8d85c80
Show file tree
Hide file tree
Showing 16 changed files with 227 additions and 51 deletions.
14 changes: 14 additions & 0 deletions packages/driver/cypress/e2e/commands/sessions/sessions.cy.js
Expand Up @@ -193,6 +193,7 @@ describe('cy.session', { retries: 0 }, () => {
it('groups session logs correctly', () => {
expect(logs[0].get()).to.deep.contain({
name: 'session',
state: 'passed',
id: sessionGroupId,
sessionInfo: {
id: 'session-1',
Expand Down Expand Up @@ -282,6 +283,7 @@ describe('cy.session', { retries: 0 }, () => {
it('groups session logs correctly', () => {
expect(logs[0].get()).to.deep.contain({
name: 'session',
state: 'passed',
id: sessionGroupId,
sessionInfo: {
id: sessionId,
Expand Down Expand Up @@ -344,6 +346,7 @@ describe('cy.session', { retries: 0 }, () => {
expect(err.message).to.contain('This error occurred while validating the created session')
expect(logs[0].get()).to.deep.contain({
name: 'session',
state: 'failed',
id: sessionGroupId,
sessionInfo: {
id: `session-${Cypress.state('test').id}`,
Expand Down Expand Up @@ -427,6 +430,7 @@ describe('cy.session', { retries: 0 }, () => {
it('groups session logs correctly', () => {
expect(logs[0].get()).to.contain({
name: 'session',
state: 'passed',
id: sessionGroupId,
})

Expand Down Expand Up @@ -490,6 +494,7 @@ describe('cy.session', { retries: 0 }, () => {
it('groups session logs correctly', () => {
expect(logs[0].get()).to.contain({
name: 'session',
state: 'passed',
id: sessionGroupId,
})

Expand Down Expand Up @@ -572,6 +577,7 @@ describe('cy.session', { retries: 0 }, () => {
it('groups session logs correctly', () => {
expect(logs[0].get()).to.contain({
name: 'session',
state: 'warned',
id: sessionGroupId,
})

Expand Down Expand Up @@ -678,6 +684,7 @@ describe('cy.session', { retries: 0 }, () => {

expect(logs[0].get()).to.contain({
name: 'session',
state: 'failed',
id: sessionGroupId,
})

Expand Down Expand Up @@ -914,6 +921,7 @@ describe('cy.session', { retries: 0 }, () => {
it('groups session logs correctly', () => {
expect(logs[0].get()).to.deep.contain({
name: 'session',
state: 'passed',
id: sessionGroupId,
sessionInfo: {
id: 'session-1',
Expand Down Expand Up @@ -992,6 +1000,7 @@ describe('cy.session', { retries: 0 }, () => {
it('groups session logs correctly', () => {
expect(logs[0].get()).to.deep.contain({
name: 'session',
state: 'passed',
id: sessionGroupId,
sessionInfo: {
id: sessionId,
Expand Down Expand Up @@ -1044,6 +1053,7 @@ describe('cy.session', { retries: 0 }, () => {
expect(err.message).to.contain('Your `cy.session` **validate** promise rejected with false')
expect(logs[0].get()).to.deep.contain({
name: 'session',
state: 'failed',
id: sessionGroupId,
sessionInfo: {
id: `session-${Cypress.state('test').id}`,
Expand Down Expand Up @@ -1121,6 +1131,7 @@ describe('cy.session', { retries: 0 }, () => {
it('groups session logs correctly', () => {
expect(logs[0].get()).to.contain({
name: 'session',
state: 'passed',
id: sessionGroupId,
})

Expand Down Expand Up @@ -1178,6 +1189,7 @@ describe('cy.session', { retries: 0 }, () => {
it('groups session logs correctly', () => {
expect(logs[0].get()).to.contain({
name: 'session',
state: 'passed',
id: sessionGroupId,
})

Expand Down Expand Up @@ -1254,6 +1266,7 @@ describe('cy.session', { retries: 0 }, () => {
it('groups session logs correctly', () => {
expect(logs[0].get()).to.contain({
name: 'session',
state: 'warned',
id: sessionGroupId,
})

Expand Down Expand Up @@ -1345,6 +1358,7 @@ describe('cy.session', { retries: 0 }, () => {

expect(logs[0].get()).to.contain({
name: 'session',
state: 'failed',
id: sessionGroupId,
})

Expand Down
32 changes: 14 additions & 18 deletions packages/driver/src/cy/commands/sessions/index.ts
Expand Up @@ -8,6 +8,7 @@ import SessionsManager from './manager'
import {
getConsoleProps,
navigateAboutBlank,
SESSION_STEPS,
statusMap,
} from './utils'

Expand Down Expand Up @@ -39,8 +40,6 @@ export default function (Commands, Cypress, cy) {
const sessionsManager = new SessionsManager(Cypress, cy)
const sessions = sessionsManager.sessions

type SESSION_STEPS = 'create' | 'restore' | 'recreate' | 'validate'

Cypress.on('run:start', () => {
// @ts-ignore
Object.values(Cypress.state('activeSessions') || {}).forEach((sessionData: ServerSessionData) => {
Expand Down Expand Up @@ -149,6 +148,7 @@ export default function (Commands, Cypress, cy) {

function setSessionLogStatus (status: string) {
_log.set({
state: statusMap.commandState(status),
sessionInfo: {
id: session.id,
isGlobalSession: session.cacheAcrossSpecs,
Expand Down Expand Up @@ -232,7 +232,7 @@ export default function (Commands, Cypress, cy) {
return sessions.setSessionData(testSession)
}

function validateSession (existingSession, step: SESSION_STEPS) {
function validateSession (existingSession, step: keyof typeof SESSION_STEPS) {
const isValidSession = true

if (!existingSession.validate) {
Expand Down Expand Up @@ -321,11 +321,7 @@ export default function (Commands, Cypress, cy) {

// skip all commands between this command which errored and _commandToRunAfterValidation
for (let i = cy.queue.index; i < index; i++) {
const cmd = commands[i]

if (!cmd.get('restore-within')) {
commands[i].skip()
}
commands[i].skip()
}

// restore within subject back to the original subject used when
Expand Down Expand Up @@ -369,7 +365,7 @@ export default function (Commands, Cypress, cy) {
}

const failValidation = (err) => {
if (step === 'restore') {
if (step === SESSION_STEPS.restore) {
enhanceErr(err)

// move to recreate session flow
Expand Down Expand Up @@ -442,13 +438,13 @@ export default function (Commands, Cypress, cy) {
.then(() => validateSession(existingSession, step))
.then(async (isValidSession: boolean) => {
if (!isValidSession) {
throw new Error('not a valid session :(')
return 'failed'
}

sessionsManager.registeredSessions.set(existingSession.id, true)
await sessions.saveSessionData(existingSession)

setSessionLogStatus(statusMap.complete(step))
return statusMap.complete(step)
})
}

Expand All @@ -460,19 +456,19 @@ export default function (Commands, Cypress, cy) {
*/
const restoreSessionWorkflow = (existingSession: SessionData) => {
return cy.then(async () => {
setSessionLogStatus('restoring')
setSessionLogStatus(statusMap.inProgress(SESSION_STEPS.restore))
await navigateAboutBlank()
await sessions.clearCurrentSessionData()

return restoreSession(existingSession)
})
.then(() => validateSession(existingSession, 'restore'))
.then(() => validateSession(existingSession, SESSION_STEPS.restore))
.then((isValidSession: boolean) => {
if (!isValidSession) {
return createSessionWorkflow(existingSession, 'recreate')
return createSessionWorkflow(existingSession, SESSION_STEPS.recreate)
}

setSessionLogStatus('restored')
return statusMap.complete(SESSION_STEPS.restore)
})
}

Expand Down Expand Up @@ -503,15 +499,15 @@ export default function (Commands, Cypress, cy) {
_.extend(session, _.omit(serverStoredSession, 'setup', 'validate'))
session.hydrated = true
} else {
return createSessionWorkflow(session, 'create')
return createSessionWorkflow(session, SESSION_STEPS.create)
}
}

return restoreSessionWorkflow(session)
}).then(() => {
}).then((status: 'created' | 'restored' | 'recreated' | 'failed') => {
return navigateAboutBlank()
.then(() => {
_log.set({ state: 'passed' })
setSessionLogStatus(status)
})
})
})
Expand Down
22 changes: 22 additions & 0 deletions packages/driver/src/cy/commands/sessions/utils.ts
Expand Up @@ -208,7 +208,28 @@ function navigateAboutBlank (session: boolean = true) {
})
}

const enum SESSION_STEPS {
create = 'create',
restore = 'restore',
recreate = 'recreate',
validate = 'validate',
}

const statusMap = {
commandState: (status: string) => {
switch (status) {
case 'failed':
return 'failed'
case 'recreating':
case 'recreated':
return 'warned'
case 'created':
case 'restored':
return 'passed'
default:
return 'pending'
}
},
inProgress: (step) => {
switch (step) {
case 'create':
Expand Down Expand Up @@ -255,5 +276,6 @@ export {
getConsoleProps,
getPostMessageLocalStorage,
navigateAboutBlank,
SESSION_STEPS,
statusMap,
}
2 changes: 1 addition & 1 deletion packages/reporter/cypress/e2e/commands.cy.ts
Expand Up @@ -848,7 +848,7 @@ describe('commands', { viewportHeight: 1000 }, () => {
})

it('shows a tooltip', () => {
cy.get('.command-name-within').click()
cy.get('.command-name-within').click('top')
cy.get('.cy-tooltip').should('have.text', 'Printed output to your console')
})

Expand Down
82 changes: 71 additions & 11 deletions packages/reporter/src/commands/command.cy.tsx
@@ -1,31 +1,91 @@
import React from 'react'
import Command from './command'
import CommandModel from './command-model'
import type { SessionStatus } from '../sessions/utils'
import type { TestState } from '@packages/types'

describe('commands', () => {
describe('test states', () => {
it('warned command', () => {
cy.mount(
<div>
<Command
key={status}
model={
new CommandModel({
name: 'session',
message: 'user1',
state: 'warned',
sessionInfo: {
id: 'user1',
isGlobalSession: false,
status: 'recreated',
},
number: 1,
type: 'parent',
hookId: '1',
testId: '1',
id: 1,
numElements: 1,
})
}
/>
</div>,
)

cy.percySnapshot()
})
})

describe('sessionPill', () => {
const statusList = [
'creating',
'created',
'restoring',
'restored',
'recreating',
'recreated',
'failed',
const statusList: Array<{
state: TestState
status: SessionStatus
}> = [
{
state: 'pending',
status: 'creating',
},
{
state: 'passed',
status: 'created',
},
{
state: 'pending',
status: 'restoring',
},
{
state: 'passed',
status: 'restored',
},
{
state: 'warned',
status: 'recreating',
},
{
state: 'warned',
status: 'recreated',
},
{
state: 'failed',
status: 'failed',
},
]

it('session status in command', () => {
cy.mount(
<div>
{statusList.map((status, index) => (
{statusList.map(({ state, status }, index) => (
<Command
key={status}
model={
new CommandModel({
name: 'session',
message: 'user1',
state: 'passed',
renderProps: {
state,
sessionInfo: {
id: 'user1',
isGlobalSession: false,
status,
},
number: index,
Expand Down
3 changes: 2 additions & 1 deletion packages/reporter/src/commands/command.tsx
Expand Up @@ -14,6 +14,7 @@ import Tag from '../lib/tag'
import { TimeoutID } from '../lib/types'
import runnablesStore, { RunnablesStore } from '../runnables/runnables-store'
import { Alias, AliasObject } from '../instruments/instrument-model'
import { determineTagType } from '../sessions/utils'

import CommandModel, { RenderProps } from './command-model'
import TestError from '../errors/test-error'
Expand Down Expand Up @@ -298,7 +299,7 @@ const CommandControls = observer(({ model, commandName, events }) => {
{isSessionCommand && (
<Tag
content={model.sessionInfo?.status}
type={`${model.sessionInfo?.status === 'failed' ? 'failed' : 'successful'}-status`}
type={determineTagType(model.state)}
/>
)}
{!model.visible && (
Expand Down

5 comments on commit 8d85c80

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 8d85c80 Nov 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/11.2.0/linux-arm64/develop-8d85c80a36c8e55bceb178bb589d1c3360576ace/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 8d85c80 Nov 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/11.2.0/linux-x64/develop-8d85c80a36c8e55bceb178bb589d1c3360576ace/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 8d85c80 Nov 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 darwin 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/11.2.0/darwin-arm64/develop-8d85c80a36c8e55bceb178bb589d1c3360576ace/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 8d85c80 Nov 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 darwin 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/11.2.0/darwin-x64/develop-8d85c80a36c8e55bceb178bb589d1c3360576ace/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 8d85c80 Nov 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/11.2.0/win32-x64/develop-8d85c80a36c8e55bceb178bb589d1c3360576ace/cypress.tgz

Please sign in to comment.