-
-
Notifications
You must be signed in to change notification settings - Fork 751
Expand file tree
/
Copy pathactor.js
More file actions
133 lines (119 loc) · 3.57 KB
/
actor.js
File metadata and controls
133 lines (119 loc) · 3.57 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
126
127
128
129
130
131
132
133
import Step, { MetaStep } from './step.js'
import recordStep from './step/record.js'
import retryStep from './step/retry.js'
import { methodsOfObject } from './utils.js'
import { TIMEOUT_ORDER } from './timeout.js'
import event from './event.js'
import store from './store.js'
import output from './output.js'
import Container from './container.js'
/**
* @interface
* @alias ActorStatic
*/
class Actor {
/**
* Print the comment on log. Also, adding a step in the `Test.steps` object
* @param {string} msg
* @param {string} color
* @inner
*
* ⚠️ returns a promise which is synchronized internally by recorder
*/
async say(msg, color = 'cyan') {
const step = new Step('say', 'say')
step.status = 'passed'
return recordStep(step, [msg]).then(() => {
// this is backward compatibility as this event may be used somewhere
event.emit(event.step.comment, msg)
output.say(msg, `${color}`)
})
}
/**
* set the maximum execution time for the next step
* @function
* @param {number} timeout - step timeout in seconds
* @return {this}
* @inner
*/
limitTime(timeout) {
if (!store.timeouts) return this
console.log('I.limitTime() is deprecated, use step.timeout() instead')
event.dispatcher.prependOnceListener(event.step.before, step => {
output.log(`Timeout to ${step}: ${timeout}s`)
step.setTimeout(timeout * 1000, TIMEOUT_ORDER.codeLimitTime)
})
return this
}
/**
* @function
* @param {*} [opts]
* @return {this}
* @inner
*/
retry(opts) {
console.log('I.retry() is deprecated, use step.retry() instead')
retryStep(opts)
return this
}
}
/**
* Fetches all methods from all enabled helpers,
* and makes them available to use from I. object
* Wraps helper methods into promises.
* @ignore
*/
export default function (obj = {}, container) {
// Use global container if none provided
if (!container) {
container = Container
}
// Get existing actor or create a new one
const actor = container.actor() || new Actor()
// load all helpers once container initialized
container.started(() => {
const translation = container.translation()
const helpers = container.helpers()
// add methods from enabled helpers
Object.values(helpers).forEach(helper => {
methodsOfObject(helper, 'Helper')
.filter(method => method !== 'constructor' && method[0] !== '_')
.forEach(action => {
const actionAlias = translation.actionAliasFor(action)
if (!actor[action]) {
actor[action] = actor[actionAlias] = function () {
const step = new Step(helper, action)
if (translation.loaded) {
step.name = actionAlias
step.actor = translation.I
}
// add methods to promise chain
return recordStep(step, Array.from(arguments))
}
}
})
})
// add translated custom steps from actor
Object.keys(obj).forEach(key => {
const actionAlias = translation.actionAliasFor(key)
if (!actor[actionAlias]) {
actor[actionAlias] = actor[key]
}
})
// Update container.support.I to ensure it has the latest actor reference
if (!container.actor() || container.actor() !== actor) {
container.append({
support: {
I: actor,
},
})
}
})
// add custom steps from actor immediately
Object.keys(obj).forEach(key => {
const ms = new MetaStep('I', key)
ms.setContext(actor)
actor[key] = ms.run.bind(ms, obj[key])
})
return actor
}