diff --git a/packages/driver/src/cypress/runner.ts b/packages/driver/src/cypress/runner.ts index 3b5e566260..7c357c6910 100644 --- a/packages/driver/src/cypress/runner.ts +++ b/packages/driver/src/cypress/runner.ts @@ -490,11 +490,13 @@ const overrideRunnerHook = (Cypress, _runner, getTestById, getTest, setTest, get topSuite = topSuite.parent } + const isRunMode = !Cypress.config('isInteractive') + const isHeadedNoExit = Cypress.config('browser').isHeaded && !Cypress.config('exit') + const shouldAlwaysResetPage = isRunMode && !isHeadedNoExit + // If we're not in open mode or we're in open mode and not the last test we reset state. // The last test will needs to stay so that the user can see what the end result of the AUT was. - const isRunMode = !Cypress.config('isInteractive') - - if (isRunMode || !lastTestThatWillRunInSuite(test, getAllSiblingTests(topSuite, getTestById))) { + if (shouldAlwaysResetPage || !lastTestThatWillRunInSuite(test, getAllSiblingTests(topSuite, getTestById))) { cy.state('duringUserTestExecution', false) Cypress.primaryOriginCommunicator.toAllSpecBridges('sync:state', { 'duringUserTestExecution': false }) // Remove window:load and window:before:load listeners so that navigating to about:blank doesn't fire in user code. diff --git a/system-tests/__snapshots__/test_isolation_spec.ts.js b/system-tests/__snapshots__/test_isolation_spec.ts.js new file mode 100644 index 0000000000..90b6cbc9a0 --- /dev/null +++ b/system-tests/__snapshots__/test_isolation_spec.ts.js @@ -0,0 +1,179 @@ +exports['Test Isolation / fires events in the right order with the right arguments - headed: false - noExit: false'] = ` + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 1 found (test-isolation.spec.js) │ + │ Searched: cypress/e2e/test-isolation.spec.js │ + │ Experiments: experimentalInteractiveRunEvents=true │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: test-isolation.spec.js (1 of 1) + + + test isolation + ✓ passes 1 + ✓ passes 2 + ✓ passes 3 + + + 3 passing + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 3 │ + │ Passing: 3 │ + │ Failing: 0 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 0 │ + │ Video: false │ + │ Duration: X seconds │ + │ Spec Ran: test-isolation.spec.js │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +==================================================================================================== + + (Run Finished) + + + Spec Tests Passing Failing Pending Skipped + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ ✔ test-isolation.spec.js XX:XX 3 3 - - - │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + ✔ All specs passed! XX:XX 3 3 - - - + + +` + +exports['Test Isolation / fires events in the right order with the right arguments - headed: true - noExit: false'] = ` + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 1 found (test-isolation.spec.js) │ + │ Searched: cypress/e2e/test-isolation.spec.js │ + │ Experiments: experimentalInteractiveRunEvents=true │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: test-isolation.spec.js (1 of 1) + + + test isolation + ✓ passes 1 + ✓ passes 2 + ✓ passes 3 + + + 3 passing + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 3 │ + │ Passing: 3 │ + │ Failing: 0 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 0 │ + │ Video: false │ + │ Duration: X seconds │ + │ Spec Ran: test-isolation.spec.js │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +==================================================================================================== + + (Run Finished) + + + Spec Tests Passing Failing Pending Skipped + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ ✔ test-isolation.spec.js XX:XX 3 3 - - - │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + ✔ All specs passed! XX:XX 3 3 - - - + + +` + +exports['Test Isolation / fires events in the right order with the right arguments - headed: true - noExit: true'] = ` + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 1 found (test-isolation.spec.js) │ + │ Searched: cypress/e2e/test-isolation.spec.js │ + │ Experiments: experimentalInteractiveRunEvents=true │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: test-isolation.spec.js (1 of 1) + + + test isolation + ✓ passes 1 + ✓ passes 2 + ✓ passes 3 + + + 3 passing + +not exiting due to options.exit being false + +` + +exports['Test Isolation / fires events in the right order with the right arguments - headed: false - noExit: true'] = ` + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 1 found (test-isolation.spec.js) │ + │ Searched: cypress/e2e/test-isolation.spec.js │ + │ Experiments: experimentalInteractiveRunEvents=true │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: test-isolation.spec.js (1 of 1) + + + test isolation + ✓ passes 1 + ✓ passes 2 + ✓ passes 3 + + + 3 passing + +not exiting due to options.exit being false + +` diff --git a/system-tests/projects/cypress-in-cypress/cypress/e2e/test-isolation.spec.js b/system-tests/projects/cypress-in-cypress/cypress/e2e/test-isolation.spec.js index 7c9ca8891d..4fa1dbfb87 100644 --- a/system-tests/projects/cypress-in-cypress/cypress/e2e/test-isolation.spec.js +++ b/system-tests/projects/cypress-in-cypress/cypress/e2e/test-isolation.spec.js @@ -1,3 +1,10 @@ +const shouldAlwaysResetPage = (config) => { + const isRunMode = !config('isInteractive') + const isHeadedNoExit = config('browser').isHeaded && !config('exit') + + return isRunMode && !isHeadedNoExit +} + const TEST_METADATA = { 'passes 1': { start: 'about:blank', @@ -12,7 +19,7 @@ const TEST_METADATA = { 'passes 3': { start: 'about:blank', firesTestBeforeAfterRunAsync: !Cypress.config('isInteractive'), - end: !Cypress.config('isInteractive') ? 'about:blank' : '/cypress/e2e/dom-content.html', + end: shouldAlwaysResetPage(Cypress.config) ? 'about:blank' : '/cypress/e2e/dom-content.html', }, } @@ -63,7 +70,7 @@ Cypress.on('test:after:run:async', async (test) => { } else if (test.title === 'passes 2') { expect(cypressEventsHandled).to.equal(10) } else if (test.title === 'passes 3') { - expect(cypressEventsHandled).to.equal(Cypress.config('isInteractive') ? 14 : 15) + expect(cypressEventsHandled).to.equal(!shouldAlwaysResetPage(Cypress.config) ? 14 : 15) } }) diff --git a/system-tests/test/test_isolation_spec.ts b/system-tests/test/test_isolation_spec.ts index e98a2d8b27..b202369683 100644 --- a/system-tests/test/test_isolation_spec.ts +++ b/system-tests/test/test_isolation_spec.ts @@ -1,4 +1,5 @@ import systemTests from '../lib/system-tests' +import childProcess from 'child_process' describe('Test Isolation', () => { systemTests.setup() @@ -10,4 +11,78 @@ describe('Test Isolation', () => { timeout: 20000, browser: 'chrome', }) + + systemTests.it('fires events in the right order with the right arguments - headed: true - noExit: true', { + config: { + env: { + 'SHOULD_PAUSE': false, + }, + }, + project: 'cypress-in-cypress', + spec: 'test-isolation.spec.js', + expectedExitCode: null, + timeout: 20000, + browser: 'chrome', + snapshot: true, + headed: true, + noExit: true, + onSpawn: (cp) => { + cp.stdout.on('data', (buf) => { + if (buf.toString().includes('not exiting due to options.exit being false')) { + // systemTests.it spawns a new node process which then spawns the actual cypress process + // Killing just the new node process doesn't kill the cypress process so we find it and kill it manually + childProcess.execSync(`kill $(pgrep -P ${cp.pid} | awk '{print $1}')`) + cp.kill() + } + }) + }, + }) + + systemTests.it('fires events in the right order with the right arguments - headed: false - noExit: true', { + config: { + env: { + 'SHOULD_PAUSE': false, + }, + }, + project: 'cypress-in-cypress', + spec: 'test-isolation.spec.js', + expectedExitCode: null, + timeout: 20000, + browser: 'chrome', + snapshot: true, + headed: false, + noExit: true, + onSpawn: (cp) => { + cp.stdout.on('data', (buf) => { + if (buf.toString().includes('not exiting due to options.exit being false')) { + // systemTests.it spawns a new node process which then spawns the actual cypress process + // Killing just the new node process doesn't kill the cypress process so we find it and kill it manually + childProcess.execSync(`kill $(pgrep -P ${cp.pid} | awk '{print $1}')`) + cp.kill() + } + }) + }, + }) + + systemTests.it('fires events in the right order with the right arguments - headed: false - noExit: false', { + project: 'cypress-in-cypress', + spec: 'test-isolation.spec.js', + expectedExitCode: 0, + timeout: 20000, + browser: 'chrome', + snapshot: true, + headed: false, + noExit: false, + }) + + systemTests.it('fires events in the right order with the right arguments - headed: true - noExit: false', { + project: 'cypress-in-cypress', + spec: 'test-isolation.spec.js', + expectedExitCode: 0, + timeout: 20000, + browser: 'chrome', + snapshot: true, + headed: true, + noExit: false, + }) })