diff --git a/lib/recorder.js b/lib/recorder.js index 006a163d8..48dcd3578 100644 --- a/lib/recorder.js +++ b/lib/recorder.js @@ -11,6 +11,7 @@ let running = false let errFn let queueId = 0 let sessionId = null +let sessionStack = [] // Stack to support nested sessions let asyncErr = null let ignoredErrs = [] @@ -89,6 +90,7 @@ module.exports = { if (promise && running) this.catch() queueId++ sessionId = null + sessionStack = [] // Clear the session stack asyncErr = null log(`${currentQueue()} Starting recording promises`) promise = Promise.resolve() @@ -123,8 +125,13 @@ module.exports = { */ start(name) { if (sessionId) { - debug(`${currentQueue()}Session already started as ${sessionId}`) - this.restore(sessionId) + debug(`${currentQueue()}Session already started as ${sessionId}, nesting session ${name}`) + // Push current session to stack instead of restoring it + sessionStack.push({ + id: sessionId, + promise: promise, + running: this.running, + }) } debug(`${currentQueue()}Starting <${name}> session`) tasks.push('--->') @@ -142,9 +149,18 @@ module.exports = { tasks.push('<---') debug(`${currentQueue()}Finalize <${name}> session`) this.running = false - sessionId = null this.catch(errFn) promise = promise.then(() => oldPromises.pop()) + + // Restore parent session from stack if available + if (sessionStack.length> 0) { + const parentSession = sessionStack.pop() + sessionId = parentSession.id + this.running = parentSession.running + debug(`${currentQueue()}Restored parent session <${sessionid}>`) + } else { + sessionId = null + } }, /** diff --git a/test/data/sandbox/base_test_session.js b/test/data/sandbox/base_test_session.js index b424acb69..41cf88780 100644 --- a/test/data/sandbox/base_test_session.js +++ b/test/data/sandbox/base_test_session.js @@ -1,40 +1,66 @@ -Feature('Session'); +Feature('Session') Scenario('basic session @1', ({ I }) => { - I.do('writing'); + I.do('writing') session('davert', () => { - I.do('reading'); - }); - I.do('playing'); + I.do('reading') + }) + I.do('playing') session('john', () => { - I.do('crying'); - }); + I.do('crying') + }) session('davert', () => { - I.do('smiling'); - }); - I.do('laughing'); + I.do('smiling') + }) + I.do('laughing') session('mike', () => { - I.do('spying'); - }); + I.do('spying') + }) session('john', () => { - I.do('lying'); - }); - I.do('waving'); -}); + I.do('lying') + }) + I.do('waving') +}) Scenario('session defined not used @2', ({ I }) => { - session('davert'); - I.do('writing'); - I.do('playing'); + session('davert') + I.do('writing') + I.do('playing') session('john', () => { - I.do('crying'); - }); + I.do('crying') + }) session('davert', () => { - I.do('smiling'); - }); - I.do('laughing'); + I.do('smiling') + }) + I.do('laughing') session('davert', () => { - I.do('singing'); - }); - I.do('waving'); -}); + I.do('singing') + }) + I.do('waving') +}) + +Scenario('tryTo inside session @3', ({ I }) => { + const { tryTo } = require('../../../lib/effects') + I.do('before session') + session('tryTo-test', async () => { + I.do('inside session') + await tryTo(() => { + I.do('inside tryTo') + }) + I.do('after tryTo') + }) + I.do('after session') +}) + +Scenario('session inside tryTo @4', ({ I }) => { + const { tryTo } = require('../../../lib/effects') + I.do('before tryTo') + tryTo(async () => { + I.do('inside tryTo') + await session('nested-session', () => { + I.do('inside nested session') + }) + I.do('after session') + }) + I.do('after tryTo') +})