Skip to content

Commit cb14ae6

Browse files
emilyrohrboughchrisbreidingAtofStryker
authored
chore(sessions): break out sessions manager code and add unit tests (#21268)
Co-authored-by: Chris Breiding <[email protected]> Co-authored-by: Bill Glesias <[email protected]>
1 parent 7a76de1 commit cb14ae6

File tree

3 files changed

+677
-308
lines changed

3 files changed

+677
-308
lines changed
Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
const SessionsManager = require('../../../../src/cy/commands/sessions/manager').default
2+
const $Cypress = require('../../../../src/cypress').default
3+
4+
describe('src/cy/commands/sessions/manager.ts', () => {
5+
let CypressInstance
6+
let baseUrl
7+
8+
beforeEach(function () {
9+
// @ts-ignore
10+
CypressInstance = new $Cypress()
11+
baseUrl = Cypress.config('baseUrl')
12+
})
13+
14+
it('creates SessionsManager instance', () => {
15+
const sessionsManager = new SessionsManager(CypressInstance, () => {})
16+
17+
expect(sessionsManager).to.haveOwnProperty('cy')
18+
expect(sessionsManager).to.haveOwnProperty('Cypress')
19+
expect(sessionsManager).to.haveOwnProperty('currentTestRegisteredSessions')
20+
expect(sessionsManager.currentTestRegisteredSessions).to.be.instanceOf(Map)
21+
})
22+
23+
describe('.setActiveSession()', () => {
24+
it('adds session when none were previously added', () => {
25+
const cySpy = cy.spy(cy, 'state').withArgs('activeSessions')
26+
27+
const activeSession: Cypress.Commands.Session.ActiveSessions = {
28+
'session_1': {
29+
id: 'session_1',
30+
setup: () => {},
31+
hydrated: true,
32+
},
33+
}
34+
35+
const sessionsManager = new SessionsManager(CypressInstance, cy)
36+
37+
sessionsManager.setActiveSession(activeSession)
38+
const calls = cySpy.getCalls()
39+
40+
expect(cySpy).to.be.calledTwice
41+
expect(calls[0].args[1]).to.be.undefined
42+
expect(calls[1].args[1]).to.haveOwnProperty('session_1')
43+
})
44+
45+
it('adds session when other sessions were previously added', () => {
46+
const existingSessions: Cypress.Commands.Session.ActiveSessions = {
47+
'session_1': {
48+
id: 'session_1',
49+
setup: () => {},
50+
hydrated: false,
51+
},
52+
'session_2': {
53+
id: 'session_2',
54+
setup: () => {},
55+
hydrated: true,
56+
},
57+
}
58+
59+
const cySpy = cy.stub(cy, 'state').callThrough().withArgs('activeSessions').returns(existingSessions)
60+
61+
const activeSession: Cypress.Commands.Session.ActiveSessions = {
62+
'session_3': {
63+
id: 'session_3',
64+
setup: () => {},
65+
hydrated: true,
66+
},
67+
}
68+
69+
const sessionsManager = new SessionsManager(CypressInstance, cy)
70+
71+
sessionsManager.setActiveSession(activeSession)
72+
const calls = cySpy.getCalls()
73+
74+
expect(cySpy).to.be.calledTwice
75+
expect(calls[0].args[1]).to.be.undefined
76+
expect(calls[1].args[1]).to.haveOwnProperty('session_1')
77+
expect(calls[1].args[1]).to.haveOwnProperty('session_2')
78+
expect(calls[1].args[1]).to.haveOwnProperty('session_3')
79+
})
80+
})
81+
82+
describe('.getActiveSession()', () => {
83+
it('returns undefined when no active sessions', () => {
84+
const cySpy = cy.stub(cy, 'state').callThrough().withArgs('activeSessions')
85+
86+
const sessionsManager = new SessionsManager(CypressInstance, cy)
87+
88+
const activeSession = sessionsManager.getActiveSession('session_1')
89+
90+
expect(cySpy).to.be.calledOnce
91+
expect(activeSession).to.be.undefined
92+
})
93+
94+
it('returns session when found', () => {
95+
const activeSessions: Cypress.Commands.Session.ActiveSessions = {
96+
'session_1': {
97+
id: 'session_1',
98+
setup: () => {},
99+
hydrated: false,
100+
},
101+
'session_2': {
102+
id: 'session_2',
103+
setup: () => {},
104+
hydrated: true,
105+
},
106+
}
107+
108+
const cySpy = cy.stub(cy, 'state').callThrough().withArgs('activeSessions').returns(activeSessions)
109+
110+
const sessionsManager = new SessionsManager(CypressInstance, cy)
111+
112+
let activeSession = sessionsManager.getActiveSession('session_1')
113+
114+
expect(cySpy).to.be.calledOnce
115+
expect(activeSession).to.deep.eq(activeSessions['session_1'])
116+
})
117+
})
118+
119+
describe('.clearActiveSessions()', () => {
120+
it('handles when no active sessions have been set', () => {
121+
const cySpy = cy.stub(cy, 'state').callThrough().withArgs('activeSessions')
122+
123+
const sessionsManager = new SessionsManager(CypressInstance, cy)
124+
125+
sessionsManager.clearActiveSessions()
126+
const calls = cySpy.getCalls()
127+
128+
expect(cySpy).to.be.calledTwice
129+
expect(calls[1].args[1]).to.be.instanceOf(Object)
130+
expect(calls[1].args[1]).to.deep.eq({})
131+
})
132+
133+
it('updates the existing active sessions to "hydrated: false"', () => {
134+
const existingSessions: Cypress.Commands.Session.ActiveSessions = {
135+
'session_1': {
136+
id: 'session_1',
137+
setup: () => {},
138+
hydrated: false,
139+
},
140+
'session_2': {
141+
id: 'session_2',
142+
setup: () => {},
143+
hydrated: true,
144+
},
145+
}
146+
147+
const cySpy = cy.stub(cy, 'state').callThrough().withArgs('activeSessions').returns(existingSessions)
148+
149+
const sessionsManager = new SessionsManager(CypressInstance, cy)
150+
151+
sessionsManager.clearActiveSessions()
152+
const calls = cySpy.getCalls()
153+
154+
expect(cySpy).to.be.calledTwice
155+
expect(calls[1].args[1]).to.be.instanceOf(Object)
156+
expect(calls[1].args[1]).to.haveOwnProperty('session_1')
157+
expect(calls[1].args[1].session_1).to.haveOwnProperty('hydrated', false)
158+
expect(calls[1].args[1]).to.haveOwnProperty('session_2')
159+
expect(calls[1].args[1].session_2).to.haveOwnProperty('hydrated', false)
160+
})
161+
})
162+
163+
describe('.mapOrigins()', () => {
164+
it('maps when requesting all origins', async () => {
165+
const sessionsManager = new SessionsManager(CypressInstance, cy)
166+
167+
const allOrigins = ['https://example.com', baseUrl, 'http://foobar.com', 'http://foobar.com']
168+
const sessionsSpy = cy.stub(sessionsManager, 'getAllHtmlOrigins').resolves(allOrigins)
169+
170+
const origins = await sessionsManager.mapOrigins('*')
171+
172+
expect(origins).to.deep.eq(['https://example.com', baseUrl, 'http://foobar.com'])
173+
expect(sessionsSpy).to.be.calledOnce
174+
})
175+
176+
it('maps when requesting the current origin', async () => {
177+
const sessionsManager = new SessionsManager(CypressInstance, cy)
178+
const sessionsSpy = cy.stub(sessionsManager, 'getAllHtmlOrigins')
179+
const origins = await sessionsManager.mapOrigins('currentOrigin')
180+
181+
expect(origins).to.deep.eq([baseUrl])
182+
expect(sessionsSpy).not.to.be.called
183+
})
184+
185+
it('maps when requesting a specific origin', async () => {
186+
const sessionsManager = new SessionsManager(CypressInstance, cy)
187+
const sessionsSpy = cy.stub(sessionsManager, 'getAllHtmlOrigins')
188+
const origins = await sessionsManager.mapOrigins('https://example.com/random_page?1')
189+
190+
expect(origins).to.deep.eq(['https://example.com'])
191+
expect(sessionsSpy).not.to.be.called
192+
})
193+
194+
it('maps when requesting a list of origins', async () => {
195+
const sessionsManager = new SessionsManager(CypressInstance, cy)
196+
197+
const allOrigins = ['https://example.com', baseUrl, 'http://foobar.com', 'http://foobar.com']
198+
const sessionsSpy = cy.stub(sessionsManager, 'getAllHtmlOrigins').resolves(allOrigins)
199+
200+
const origins = await sessionsManager.mapOrigins(['*', 'https://other.com'])
201+
202+
expect(origins).to.deep.eq(['https://example.com', baseUrl, 'http://foobar.com', 'https://other.com'])
203+
expect(sessionsSpy).to.be.calledOnce
204+
})
205+
})
206+
207+
// TODO:
208+
describe('._setStorageOnOrigins()', () => {})
209+
210+
it('.getAllHtmlOrigins()', async () => {
211+
const storedOrigins = {
212+
'https://example.com': {},
213+
'https://foobar.com': {},
214+
}
215+
216+
storedOrigins[`${baseUrl}`] = {}
217+
const cypressSpy = cy.stub(CypressInstance, 'backend').callThrough().withArgs('get:rendered:html:origins').resolves(storedOrigins)
218+
const sessionsManager = new SessionsManager(CypressInstance, cy)
219+
220+
const origins = await sessionsManager.getAllHtmlOrigins()
221+
222+
expect(cypressSpy).have.been.calledOnce
223+
expect(origins).to.have.lengthOf(3)
224+
expect(origins).to.deep.eq(['https://example.com', 'https://foobar.com', baseUrl])
225+
})
226+
227+
describe('.sessions', () => {
228+
it('sessions.defineSession()', () => {
229+
const sessionsManager = new SessionsManager(CypressInstance, cy)
230+
const sessionsSpy = cy.stub(sessionsManager, 'setActiveSession')
231+
const setup = cy.stub()
232+
const sess = sessionsManager.sessions.defineSession({ id: '1', setup })
233+
234+
expect(sess).to.deep.eq({
235+
id: '1',
236+
setup,
237+
validate: undefined,
238+
cookies: null,
239+
localStorage: null,
240+
hydrated: false,
241+
})
242+
243+
expect(sessionsSpy).to.be.calledOnce
244+
expect(sessionsSpy.getCall(0).args[0]).to.deep.eq({ 1: sess })
245+
})
246+
247+
it('sessions.clearAllSavedSessions()', async () => {
248+
const cypressSpy = cy.stub(CypressInstance, 'backend').withArgs('clear:session').resolves(null)
249+
250+
const sessionsManager = new SessionsManager(CypressInstance, () => {})
251+
const sessionsSpy = cy.stub(sessionsManager, 'clearActiveSessions')
252+
253+
await sessionsManager.sessions.clearAllSavedSessions()
254+
255+
expect(sessionsSpy).to.be.calledOnce
256+
expect(cypressSpy).to.be.calledOnceWith('clear:session', null)
257+
})
258+
259+
it('.clearCurrentSessionData()', async () => {
260+
// Unable to cleanly mock localStorage or sessionStorage on Firefox,
261+
// so add dummy values and ensure they are cleared as expected.
262+
// https://bugzilla.mozilla.org/show_bug.cgi?id=1141698
263+
window.localStorage.foo = 'bar'
264+
window.sessionStorage.jazzy = 'music'
265+
266+
expect(window.localStorage).of.have.lengthOf(1)
267+
expect(window.sessionStorage).of.have.lengthOf(1)
268+
269+
const sessionsManager = new SessionsManager(CypressInstance, () => {})
270+
271+
const clearStorageSpy = cy.stub(sessionsManager.sessions, 'clearStorage')
272+
const clearCookiesSpy = cy.stub(sessionsManager.sessions, 'clearCookies')
273+
274+
await sessionsManager.sessions.clearCurrentSessionData()
275+
276+
expect(clearStorageSpy).to.be.calledOnce
277+
expect(clearCookiesSpy).to.be.calledOnce
278+
expect(window.localStorage).of.have.lengthOf(0)
279+
expect(window.sessionStorage).of.have.lengthOf(0)
280+
})
281+
282+
// TODO:
283+
describe('sessions.setSessionData', () => {})
284+
285+
it('sessions.getCookies()', async () => {
286+
const cookies = [{ id: 'cookie' }]
287+
const cypressSpy = cy.stub(CypressInstance, 'automation').withArgs('get:cookies').resolves(cookies)
288+
289+
const sessionsManager = new SessionsManager(CypressInstance, () => {})
290+
291+
const sessionCookies = await sessionsManager.sessions.getCookies()
292+
293+
expect(cypressSpy).to.be.calledOnceWith('get:cookies', {})
294+
expect(sessionCookies).to.deep.eq(cookies)
295+
})
296+
297+
it('sessions.setCookies()', async () => {
298+
const cypressSpy = cy.stub(CypressInstance, 'automation').withArgs('set:cookies')
299+
300+
const sessionsManager = new SessionsManager(CypressInstance, () => {})
301+
302+
await sessionsManager.sessions.setCookies({})
303+
304+
expect(cypressSpy).to.be.calledOnceWith('set:cookies', {})
305+
})
306+
307+
it('sessions.clearCookies()', async () => {
308+
const cookies = [{ id: 'cookie' }]
309+
const cypressSpy = cy.stub(CypressInstance, 'automation').withArgs('clear:cookies').resolves([])
310+
311+
const sessionsManager = new SessionsManager(CypressInstance, () => {})
312+
const sessionsSpy = cy.stub(sessionsManager.sessions, 'getCookies').resolves(cookies)
313+
314+
await sessionsManager.sessions.clearCookies()
315+
316+
expect(sessionsSpy).to.be.calledOnce
317+
expect(cypressSpy).to.be.calledOnceWith('clear:cookies', cookies)
318+
})
319+
320+
it('sessions.getCurrentSessionData', async () => {
321+
const sessionsManager = new SessionsManager(CypressInstance, () => {})
322+
const getStorageSpy = cy.stub(sessionsManager.sessions, 'getStorage').resolves({ localStorage: [] })
323+
const cookiesSpy = cy.stub(sessionsManager.sessions, 'getCookies').resolves([{ id: 'cookie' }])
324+
325+
const sessData = await sessionsManager.sessions.getCurrentSessionData()
326+
327+
expect(sessData).to.deep.eq({
328+
localStorage: [],
329+
cookies: [{ id: 'cookie' }],
330+
})
331+
332+
expect(getStorageSpy).to.be.calledOnce
333+
expect(cookiesSpy).to.be.calledOnce
334+
})
335+
336+
it('sessions.getSession()', () => {
337+
const cypressSpy = cy.stub(CypressInstance, 'backend').callThrough().withArgs('get:session')
338+
339+
const sessionsManager = new SessionsManager(CypressInstance, () => {})
340+
341+
sessionsManager.sessions.getSession('session_1')
342+
343+
expect(cypressSpy).to.be.calledOnceWith('get:session', 'session_1')
344+
})
345+
346+
// TODO:
347+
describe('sessions.getStorage', () => {})
348+
349+
// TODO:
350+
describe('sessions.clearStorage', () => {})
351+
352+
// TODO:
353+
describe('sessions.setStorage', () => {})
354+
})
355+
})

0 commit comments

Comments
 (0)