mirror of
https://github.com/cypress-io/cypress.git
synced 2026-04-22 23:20:24 -05:00
fix: clear session state when changing specs in open mode (#23146)
This commit is contained in:
@@ -90,7 +90,6 @@ describe(ruleName, () => {
|
||||
})
|
||||
|
||||
expect(result.errorCount).toBe(1)
|
||||
// console.log(result.messages[0].message)
|
||||
|
||||
expect(result.messages[0].message).toContain('someFn')
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ describe('skip-comment', () => {
|
||||
})
|
||||
|
||||
expect(result.errorCount).toBe(3)
|
||||
// console.log(result.messages[0].message)
|
||||
|
||||
expect(result.messages[0].message).toContain('it')
|
||||
expect(result.messages[0].message).toContain('NOTE:')
|
||||
@@ -82,7 +81,6 @@ describe('skip-comment', () => {
|
||||
})
|
||||
|
||||
expect(result.errorCount).toBe(1)
|
||||
// console.log(result.messages[0].message)
|
||||
|
||||
expect(result.messages[0].message).toContain('it')
|
||||
expect(result.messages[0].message).toContain('FOOBAR:')
|
||||
|
||||
@@ -111,7 +111,6 @@ exports.runTest = async (options = {}) => {
|
||||
})
|
||||
}
|
||||
|
||||
// console.log(stdout)
|
||||
console.log(`${chalk.bold('run matched these results:')} ${JSON.stringify(opts.expectedResults, null, 2)}`)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -45,12 +45,12 @@ describe('runner/cypress sessions.ui.spec', {
|
||||
passCount: 1,
|
||||
})
|
||||
|
||||
validateSessionsInstrumentPanel(['blank_session'])
|
||||
validateSessionsInstrumentPanel(['user1'])
|
||||
|
||||
cy.get('.command-name-session')
|
||||
.within(() => {
|
||||
cy.get('.command-expander').first().click()
|
||||
cy.contains('blank_session')
|
||||
cy.contains('user1')
|
||||
cy.contains('created')
|
||||
|
||||
validateSetupSessionGroup()
|
||||
@@ -309,3 +309,63 @@ describe('runner/cypress sessions.ui.spec', {
|
||||
cy.percySnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
describe('runner/cypress sessions.open_mode.spec', () => {
|
||||
beforeEach(() => {
|
||||
cy.scaffoldProject('session-and-origin-e2e-specs')
|
||||
cy.openProject('session-and-origin-e2e-specs')
|
||||
cy.startAppServer('e2e')
|
||||
cy.visitApp()
|
||||
|
||||
cy.get('[data-cy-row="multiple_sessions.cy.js"]').click()
|
||||
cy.waitForSpecToFinish({
|
||||
passCount: 1,
|
||||
})
|
||||
|
||||
cy.get('.command-name-session').should('contain', 'user1')
|
||||
.find('.reporter-tag').should('contain', 'created')
|
||||
|
||||
cy.get('.command-name-session').should('contain', 'user2')
|
||||
.find('.reporter-tag').should('contain', 'created')
|
||||
})
|
||||
|
||||
it('persists spec sessions when clicking "rerun all tests" button', () => {
|
||||
cy.get('.restart').click()
|
||||
|
||||
cy.waitForSpecToFinish({
|
||||
passCount: 1,
|
||||
})
|
||||
|
||||
cy.get('.command-name-session').should('contain', 'user1')
|
||||
.find('.reporter-tag').should('contain', 'restored')
|
||||
|
||||
cy.get('.command-name-session').should('contain', 'user2')
|
||||
.find('.reporter-tag').should('contain', 'restored')
|
||||
})
|
||||
|
||||
it('persists spec sessions on refresh', () => {
|
||||
cy.get('body').type('r')
|
||||
|
||||
cy.waitForSpecToFinish({
|
||||
passCount: 1,
|
||||
})
|
||||
|
||||
cy.get('.command-name-session').should('contain', 'user1')
|
||||
.find('.reporter-tag').should('contain', 'restored')
|
||||
|
||||
cy.get('.command-name-session').should('contain', 'user2')
|
||||
.find('.reporter-tag').should('contain', 'restored')
|
||||
})
|
||||
|
||||
it('does not persists spec sessions when selecting a different spec', () => {
|
||||
cy.get('body').type('f')
|
||||
cy.get('div[title="new_session.cy.js"]').click()
|
||||
|
||||
cy.waitForSpecToFinish({
|
||||
passCount: 1,
|
||||
})
|
||||
|
||||
cy.get('.command-name-session').should('contain', 'user1')
|
||||
.find('.reporter-tag').should('contain', 'created')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { shouldHaveTestResults } from '../runner/support/spec-loader'
|
||||
|
||||
declare global {
|
||||
namespace Cypress {
|
||||
interface Chainable {
|
||||
@@ -9,7 +11,11 @@ declare global {
|
||||
* 3. Waits (with a timeout of 30s) for the Rerun all tests button to be present. This ensures all tests have completed
|
||||
*
|
||||
*/
|
||||
waitForSpecToFinish(): void
|
||||
waitForSpecToFinish(expectedResults?: {
|
||||
passCount?: number
|
||||
failCount?: number
|
||||
pendingCount?: number
|
||||
}): void
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +23,7 @@ declare global {
|
||||
// Here we export the function with no intention to import it
|
||||
// This only tells the typescript type checker that this definitely is a module
|
||||
// This way, we are allowed to use the global namespace declaration
|
||||
export const waitForSpecToFinish = () => {
|
||||
export const waitForSpecToFinish = (expectedResults) => {
|
||||
// First ensure the test is loaded
|
||||
cy.get('.passed > .num').should('contain', '--')
|
||||
cy.get('.failed > .num').should('contain', '--')
|
||||
@@ -27,6 +33,10 @@ export const waitForSpecToFinish = () => {
|
||||
|
||||
// Then ensure the tests have finished
|
||||
cy.get('[aria-label="Rerun all tests"]', { timeout: 30000 })
|
||||
|
||||
if (expectedResults) {
|
||||
shouldHaveTestResults(expectedResults)
|
||||
}
|
||||
}
|
||||
|
||||
Cypress.Commands.add('waitForSpecToFinish', waitForSpecToFinish)
|
||||
|
||||
@@ -104,8 +104,9 @@ const configChangeHandler: SubscriptionHandlerArg<any, any> = (
|
||||
window.__CYPRESS_CONFIG__ = next.configChange.serveConfig
|
||||
|
||||
const eventManager = useEventManager()
|
||||
const isRerun = true
|
||||
|
||||
eventManager.runSpec()
|
||||
eventManager.runSpec(isRerun)
|
||||
} catch (e) {
|
||||
// eventManager may not be defined, for example if the spec
|
||||
// is still loading.
|
||||
|
||||
@@ -86,8 +86,6 @@ describe('SnapshotControls', { viewportHeight: 200, viewportWidth: 500 }, () =>
|
||||
// simulate it by registering the same unpin:snapshot event it does.
|
||||
eventManager.on('unpin:snapshot', () => snapshotStore.$reset())
|
||||
|
||||
// debugger
|
||||
// console.log('snapshotWithSnapshots', snapshotWithSnapshots)
|
||||
snapshotStore.pinSnapshot({ ...snapshotWithSnapshots, $el: document.body })
|
||||
|
||||
mountSnapshotControls(eventManager, autIframe)
|
||||
|
||||
@@ -90,7 +90,7 @@ export class EventManager {
|
||||
return
|
||||
}
|
||||
|
||||
return this.runSpec(state)
|
||||
return this.rerunSpec()
|
||||
}
|
||||
|
||||
const connectionInfo: AddGlobalListenerOptions = {
|
||||
@@ -719,15 +719,19 @@ export class EventManager {
|
||||
this.ws.off()
|
||||
}
|
||||
|
||||
async teardown (state: MobxRunnerStore) {
|
||||
async teardown (state: MobxRunnerStore, isRerun = false) {
|
||||
if (!Cypress) {
|
||||
return
|
||||
}
|
||||
|
||||
state.setIsLoading(true)
|
||||
|
||||
// when we are re-running we first
|
||||
// need to stop cypress always
|
||||
if (!isRerun) {
|
||||
// only clear session state when a new spec is selected
|
||||
Cypress.backend('reset:session:state')
|
||||
}
|
||||
|
||||
// when we are re-running we first need to stop cypress always
|
||||
Cypress.stop()
|
||||
// Clean up the primary communicator to prevent possible memory leaks / dangling references before the Cypress instance is destroyed.
|
||||
Cypress.primaryOriginCommunicator.removeAllListeners()
|
||||
@@ -744,26 +748,19 @@ export class EventManager {
|
||||
})
|
||||
}
|
||||
|
||||
async _rerun () {
|
||||
await this.resetReporter()
|
||||
|
||||
// this probably isn't 100% necessary
|
||||
// since Cypress will fall out of scope
|
||||
// but we want to be aggressive here
|
||||
// and force GC early and often
|
||||
Cypress.removeAllListeners()
|
||||
|
||||
this.localBus.emit('restart')
|
||||
}
|
||||
|
||||
async runSpec (state: MobxRunnerStore) {
|
||||
if (!Cypress) {
|
||||
async rerunSpec () {
|
||||
if (!this || !Cypress) {
|
||||
// if the tests have been reloaded then there is nothing to rerun
|
||||
return
|
||||
}
|
||||
|
||||
await this.teardown(state)
|
||||
await this.resetReporter()
|
||||
|
||||
return this._rerun()
|
||||
// this probably isn't 100% necessary since Cypress will fall out of scope
|
||||
// but we want to be aggressive here and force GC early and often
|
||||
Cypress.removeAllListeners()
|
||||
|
||||
this.localBus.emit('restart')
|
||||
}
|
||||
|
||||
_interceptStudio (displayProps) {
|
||||
|
||||
@@ -165,10 +165,10 @@ function getSpecUrl (namespace: string, specSrc: string) {
|
||||
* This should be called before you execute a spec,
|
||||
* or re-running the current spec.
|
||||
*/
|
||||
function teardownSpec () {
|
||||
function teardownSpec (isRerun: boolean = false) {
|
||||
useSnapshotStore().$reset()
|
||||
|
||||
return getEventManager().teardown(getMobxRunnerStore())
|
||||
return getEventManager().teardown(getMobxRunnerStore(), isRerun)
|
||||
}
|
||||
|
||||
let isTorndown = false
|
||||
@@ -399,8 +399,8 @@ async function initialize () {
|
||||
* 5. Setup the spec. This involves a few things, see the `runSpecCT` function's
|
||||
* description for more information.
|
||||
*/
|
||||
async function executeSpec (spec: SpecFile) {
|
||||
await teardownSpec()
|
||||
async function executeSpec (spec: SpecFile, isRerun: boolean = false) {
|
||||
await teardownSpec(isRerun)
|
||||
|
||||
const mobxRunnerStore = getMobxRunnerStore()
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@ export function useEventManager () {
|
||||
const autStore = useAutStore()
|
||||
const specStore = useSpecStore()
|
||||
|
||||
function runSpec () {
|
||||
function runSpec (isRerun: boolean = false) {
|
||||
if (!specStore.activeSpec) {
|
||||
throw Error(`Cannot run spec when specStore.active spec is null or undefined!`)
|
||||
}
|
||||
|
||||
autStore.setScriptError(null)
|
||||
UnifiedRunnerAPI.executeSpec(specStore.activeSpec)
|
||||
UnifiedRunnerAPI.executeSpec(specStore.activeSpec, isRerun)
|
||||
}
|
||||
|
||||
function initializeRunnerLifecycleEvents () {
|
||||
@@ -23,7 +23,9 @@ export function useEventManager () {
|
||||
eventManager.on('restart', () => {
|
||||
// If we get the event to restart but have already navigated away from the runner, don't execute the spec
|
||||
if (specStore.activeSpec) {
|
||||
runSpec()
|
||||
const isRerun = true
|
||||
|
||||
runSpec(isRerun)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -575,12 +575,12 @@ class $Cypress {
|
||||
return this.emit('after:all:screenshots', ...args)
|
||||
|
||||
case 'command:log:added':
|
||||
this.runner.addLog(args[0], this.config('isInteractive'))
|
||||
this.runner?.addLog(args[0], this.config('isInteractive'))
|
||||
|
||||
return this.emit('log:added', ...args)
|
||||
|
||||
case 'command:log:changed':
|
||||
this.runner.addLog(args[0], this.config('isInteractive'))
|
||||
this.runner?.addLog(args[0], this.config('isInteractive'))
|
||||
|
||||
return this.emit('log:changed', ...args)
|
||||
|
||||
|
||||
@@ -420,12 +420,6 @@ const _moveCursorToLineStartOrEnd = function (toStart: boolean, el: HTMLElement)
|
||||
|
||||
return
|
||||
}
|
||||
// const doc = $document.getDocumentFromElement(el)
|
||||
// console.log(doc.activeElement)
|
||||
// $elements.callNativeMethod(doc, 'execCommand', 'selectall', false)
|
||||
// $elements.callNativeMethod(el, 'select')
|
||||
// _getSelectionByEl(el).ca
|
||||
// toStart ? _getSelectionByEl(el).collapseToStart : _getSelectionByEl(el).collapseToEnd()
|
||||
|
||||
if (isTextarea) {
|
||||
const bounds = _getSelectionBoundsFromTextarea(el)
|
||||
|
||||
@@ -466,9 +466,7 @@ export class SocketBase {
|
||||
case 'get:rendered:html:origins':
|
||||
return options.getRenderedHTMLOrigins()
|
||||
case 'reset:rendered:html:origins': {
|
||||
resetRenderedHTMLOrigins()
|
||||
|
||||
return
|
||||
return resetRenderedHTMLOrigins()
|
||||
}
|
||||
case 'cross:origin:bridge:ready':
|
||||
return this.localBus.emit('cross:origin:bridge:ready', args[0])
|
||||
@@ -479,9 +477,7 @@ export class SocketBase {
|
||||
case 'cross:origin:automation:cookies:received':
|
||||
return this.localBus.emit('cross:origin:automation:cookies:received')
|
||||
default:
|
||||
throw new Error(
|
||||
`You requested a backend event we cannot handle: ${eventName}`,
|
||||
)
|
||||
throw new Error(`You requested a backend event we cannot handle: ${eventName}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,8 +95,6 @@ export async function spawned (
|
||||
|
||||
const [executable, ...rest] = command.split(' ')
|
||||
|
||||
// console.log(useExecutable, rest, spawnOpts)
|
||||
|
||||
const cp = universalSpawn(executable, rest, {
|
||||
stdio: 'pipe',
|
||||
...spawnOpts,
|
||||
@@ -133,13 +131,6 @@ export async function forked (
|
||||
) {
|
||||
const { waitForExit, waitForData, tapErr, tapOut, ...spawnOpts } = opts
|
||||
|
||||
// console.log(args)
|
||||
|
||||
// let useExecutable = executable
|
||||
// if (process.platform === 'win32' && !useExecutable.endsWith('.cmd')) {
|
||||
// useExecutable = `${executable}.cmd`
|
||||
// }
|
||||
|
||||
const cp = fork(modulePath, args, {
|
||||
stdio: 'pipe',
|
||||
...spawnOpts,
|
||||
|
||||
@@ -5,7 +5,6 @@ const urls = [
|
||||
]
|
||||
|
||||
function incrState (key) {
|
||||
// console.log(key)
|
||||
cy.log(key)
|
||||
cy.task('incrState', key)
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
it('t1', () => {
|
||||
const setupFn = cy.stub().as('runSetup')
|
||||
|
||||
cy.session('blank_session', setupFn)
|
||||
cy.session('user1', setupFn)
|
||||
cy.log('after')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user