forked from codeceptjs/CodeceptJS
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsession.js
More file actions
125 lines (105 loc) · 3.51 KB
/
session.js
File metadata and controls
125 lines (105 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
const recorder = require('./recorder');
const container = require('./container');
const event = require('./event');
const output = require('./output');
const store = require('./store');
const { isAsyncFunction } = require('./utils');
const sessionColors = [
'cyan',
'blue',
'red',
'magenta',
'yellow',
];
const savedSessions = {};
function session(sessionName, config, fn) {
if (typeof config === 'function') {
if (typeof fn === 'function') {
config = config();
} else {
// no config but with function
fn = config;
config = {};
}
}
// session helpers won't use beforeSuite and afterSuite hooks...
// restart: false options are not allowed as well
// but those helpers should be already started so inside listener/helpers.js the `_init` method should already be called
const helpers = container.helpers();
if (!savedSessions[sessionName]) {
for (const helper in helpers) {
if (!helpers[helper]._session) continue;
savedSessions[sessionName] = Object.assign({
start: () => null,
stop: () => null,
loadVars: () => null,
restoreVars: () => null,
}, store.dryRun ? {} : helpers[helper]._session());
break;
}
const closeBrowsers = () => {
const session = savedSessions[sessionName];
if (!session) return;
session.stop(session.vars);
delete savedSessions[sessionName];
};
event.dispatcher.once(event.test.finished, () => closeBrowsers());
if (!savedSessions[sessionName]) {
throw new Error('Configured helpers do not support starting sessions. Please use a helper with session support.');
}
recorder.add('save vars', async () => {
savedSessions[sessionName].vars = await savedSessions[sessionName].start(config);
});
}
// pick random color
const color = sessionColors[Object.keys(savedSessions).indexOf(sessionName) % sessionColors.length];
const addContextToStep = (step) => {
step.actor = `${output.colors[color](sessionName)}: I`;
};
if (!fn) return; // no current session steps
return recorder.add('register session wrapper', async () => {
const session = savedSessions[sessionName];
recorder.session.start(`session:${sessionName}`);
event.dispatcher.on(event.step.after, addContextToStep);
recorder.add('switch to browser', () => {
const session = savedSessions[sessionName];
return session.loadVars(session.vars);
});
const finalize = () => {
recorder.add('Finalize session', async () => {
output.stepShift = 0;
event.dispatcher.removeListener(event.step.after, addContextToStep);
await session.restoreVars();
recorder.session.restore(`session:${sessionName}`);
});
};
if (isAsyncFunction(fn)) {
return fn.apply(null).then((res) => {
finalize();
return recorder.promise().then(() => res);
}).catch((e) => {
output.stepShift = 0;
session.restoreVars();
event.dispatcher.removeListener(event.step.after, addContextToStep);
recorder.throw(e);
return recorder.promise();
});
}
let res;
try {
res = fn.apply(null);
} catch (err) {
recorder.throw(err);
} finally {
recorder.catch((e) => {
session.restoreVars();
output.stepShift = 0;
event.dispatcher.removeListener(event.step.after, addContextToStep);
throw e;
});
}
finalize();
return recorder.promise().then(() => res);
}, false, false);
}
module.exports = session;