1 | (function (factory) {
|
2 | if (typeof module === "object" && typeof module.exports === "object") {
|
3 | var v = factory(require, exports);
|
4 | if (v !== undefined) module.exports = v;
|
5 | }
|
6 | else if (typeof define === "function" && define.amd) {
|
7 | define(["require", "exports", "@theintern/common", "./Deferred", "./common/util"], factory);
|
8 | }
|
9 | })(function (require, exports) {
|
10 | "use strict";
|
11 | Object.defineProperty(exports, "__esModule", { value: true });
|
12 | var common_1 = require("@theintern/common");
|
13 | var Deferred_1 = require("./Deferred");
|
14 | var util_1 = require("./common/util");
|
15 | var Test = (function () {
|
16 | function Test(options) {
|
17 | var _this = this;
|
18 | this._hasPassed = false;
|
19 | this._isAsync = false;
|
20 | this._usesRemote = false;
|
21 | if (!options.name || !options.test) {
|
22 | throw new Error('A Test requires a name and a test function');
|
23 | }
|
24 | ['timeElapsed', 'hasPassed'].forEach(function (property) {
|
25 | var name = property;
|
26 | if (options[name] != null) {
|
27 | _this["_" + name] = options[name];
|
28 | }
|
29 | delete options[name];
|
30 | });
|
31 | Object.assign(this, options);
|
32 | }
|
33 | Object.defineProperty(Test.prototype, "executor", {
|
34 | get: function () {
|
35 | return this.parent && this.parent.executor;
|
36 | },
|
37 | enumerable: true,
|
38 | configurable: true
|
39 | });
|
40 | Object.defineProperty(Test.prototype, "hasPassed", {
|
41 | get: function () {
|
42 | return this._hasPassed;
|
43 | },
|
44 | enumerable: true,
|
45 | configurable: true
|
46 | });
|
47 | Object.defineProperty(Test.prototype, "id", {
|
48 | get: function () {
|
49 | var name = [];
|
50 | var suiteOrTest = this;
|
51 | do {
|
52 | suiteOrTest.name != null && name.unshift(suiteOrTest.name);
|
53 | } while ((suiteOrTest = suiteOrTest.parent));
|
54 | return name.join(' - ');
|
55 | },
|
56 | enumerable: true,
|
57 | configurable: true
|
58 | });
|
59 | Object.defineProperty(Test.prototype, "isAsync", {
|
60 | get: function () {
|
61 | return this._isAsync;
|
62 | },
|
63 | enumerable: true,
|
64 | configurable: true
|
65 | });
|
66 | Object.defineProperty(Test.prototype, "parentId", {
|
67 | get: function () {
|
68 | return this.parent.id;
|
69 | },
|
70 | enumerable: true,
|
71 | configurable: true
|
72 | });
|
73 | Object.defineProperty(Test.prototype, "remote", {
|
74 | get: function () {
|
75 | this._usesRemote = true;
|
76 | return this.parent.remote;
|
77 | },
|
78 | enumerable: true,
|
79 | configurable: true
|
80 | });
|
81 | Object.defineProperty(Test.prototype, "sessionId", {
|
82 | get: function () {
|
83 | return this.parent.sessionId;
|
84 | },
|
85 | enumerable: true,
|
86 | configurable: true
|
87 | });
|
88 | Object.defineProperty(Test.prototype, "timeElapsed", {
|
89 | get: function () {
|
90 | return this._timeElapsed;
|
91 | },
|
92 | enumerable: true,
|
93 | configurable: true
|
94 | });
|
95 | Object.defineProperty(Test.prototype, "timeout", {
|
96 | get: function () {
|
97 | if (this._timeout != null) {
|
98 | return this._timeout;
|
99 | }
|
100 | if (this.parent && this.parent.timeout != null) {
|
101 | return this.parent.timeout;
|
102 | }
|
103 | return 30000;
|
104 | },
|
105 | set: function (value) {
|
106 | this._timeout = value;
|
107 | },
|
108 | enumerable: true,
|
109 | configurable: true
|
110 | });
|
111 | Test.prototype.async = function (timeout, numCallsUntilResolution) {
|
112 | this._isAsync = true;
|
113 | if (timeout != null) {
|
114 | this.timeout = timeout;
|
115 | }
|
116 | var remainingCalls = numCallsUntilResolution || 1;
|
117 | var dfd = new Deferred_1.default();
|
118 | var oldResolve = dfd.resolve;
|
119 | dfd.resolve = function (value) {
|
120 | --remainingCalls;
|
121 | if (remainingCalls === 0) {
|
122 | oldResolve.call(this, value);
|
123 | }
|
124 | else if (remainingCalls < 0) {
|
125 | throw new Error('resolve called too many times');
|
126 | }
|
127 | };
|
128 | this.async = function () {
|
129 | return dfd;
|
130 | };
|
131 | return dfd;
|
132 | };
|
133 | Test.prototype.restartTimeout = function (timeout) {
|
134 | var _this = this;
|
135 | if (timeout != null) {
|
136 | this.timeout = timeout;
|
137 | }
|
138 | if (this._runTask) {
|
139 | if (this._timer) {
|
140 | clearTimeout(this._timer);
|
141 | }
|
142 | this._timer = setTimeout(function () {
|
143 | _this._timer = undefined;
|
144 | if (_this._runTask) {
|
145 | var error = new Error("Timeout reached on " + _this.id + "#");
|
146 | error.name = 'TimeoutError';
|
147 | _this.error = error;
|
148 | _this._runTask.cancel();
|
149 | }
|
150 | }, this.timeout);
|
151 | }
|
152 | };
|
153 | Test.prototype.run = function () {
|
154 | var _this = this;
|
155 | var startTime;
|
156 | if (this._runTask) {
|
157 | this._runTask.cancel();
|
158 | this._runTask = undefined;
|
159 | }
|
160 | if (this._timer) {
|
161 | clearTimeout(this._timer);
|
162 | this._timer = undefined;
|
163 | }
|
164 | this._usesRemote = false;
|
165 | this._hasPassed = false;
|
166 | this._isAsync = false;
|
167 | this._timeElapsed = 0;
|
168 | this._runTask = undefined;
|
169 | this.async = Object.getPrototypeOf(this).async;
|
170 | this.error = undefined;
|
171 | this.skipped = undefined;
|
172 | return this.executor
|
173 | .emit('testStart', this)
|
174 | .then(function () {
|
175 | startTime = Date.now();
|
176 | })
|
177 | .then(function () {
|
178 | var result = _this.test(_this);
|
179 | if (_this.isAsync) {
|
180 | if (!common_1.isPromiseLike(result)) {
|
181 | result = _this.async().promise;
|
182 | }
|
183 | else {
|
184 | result = common_1.Task.race([_this.async().promise, result]);
|
185 | }
|
186 | }
|
187 | if (common_1.isPromiseLike(result)) {
|
188 | _this._isAsync = true;
|
189 | return new common_1.Task(function (resolve, reject) {
|
190 | _this._runTask = new common_1.Task(function (resolve, reject) {
|
191 | var settled = false;
|
192 | if (common_1.isPromiseLike(result)) {
|
193 | result.then(function () {
|
194 | settled = true;
|
195 | resolve();
|
196 | }, function (error) {
|
197 | settled = true;
|
198 | reject(error);
|
199 | });
|
200 | }
|
201 | if (common_1.isTask(result)) {
|
202 | result
|
203 | .finally(function () {
|
204 | if (!settled) {
|
205 | _this.skipped = 'Canceled';
|
206 | reject(exports.SKIP);
|
207 | }
|
208 | })
|
209 | .catch(function (_error) { });
|
210 | }
|
211 | }, function () {
|
212 | if (common_1.isTask(result)) {
|
213 | result.cancel();
|
214 | }
|
215 | if (_this.error) {
|
216 | reject(_this.error);
|
217 | }
|
218 | }).then(function () {
|
219 | resolve();
|
220 | }, reject);
|
221 | _this.restartTimeout();
|
222 | });
|
223 | }
|
224 | })
|
225 | .finally(function () {
|
226 | if (_this._runTask) {
|
227 | _this._runTask.cancel();
|
228 | }
|
229 | _this._runTask = undefined;
|
230 | _this._timeElapsed = Date.now() - startTime;
|
231 | if (_this._timer) {
|
232 | clearTimeout(_this._timer);
|
233 | _this._timer = undefined;
|
234 | }
|
235 | })
|
236 | .then(function () {
|
237 | if (_this._usesRemote && !_this.isAsync) {
|
238 | throw new Error('Remote used in synchronous test! Tests using this.remote must ' +
|
239 | 'return a promise or resolve a this.async deferred.');
|
240 | }
|
241 | _this._hasPassed = true;
|
242 | })
|
243 | .catch(function (error) {
|
244 | if (error === exports.SKIP) {
|
245 | if (!_this.skipped) {
|
246 | var parentSkipped = _this.parent && _this.parent.skipped;
|
247 | _this.skipped = parentSkipped || 'suite skipped';
|
248 | }
|
249 | }
|
250 | else {
|
251 | _this.error = error;
|
252 | throw error;
|
253 | }
|
254 | })
|
255 | .finally(function () { return _this.executor.emit('testEnd', _this); });
|
256 | };
|
257 | Test.prototype.skip = function (message) {
|
258 | if (message === void 0) { message = 'skipped'; }
|
259 | this.skipped = message;
|
260 | throw exports.SKIP;
|
261 | };
|
262 | Test.prototype.toJSON = function () {
|
263 | var _this = this;
|
264 | var json = {};
|
265 | var properties = [
|
266 | 'id',
|
267 | 'parentId',
|
268 | 'name',
|
269 | 'sessionId',
|
270 | 'timeElapsed',
|
271 | 'timeout',
|
272 | 'hasPassed',
|
273 | 'skipped'
|
274 | ];
|
275 | properties.forEach(function (key) {
|
276 | var value = _this[key];
|
277 | if (typeof value !== 'undefined') {
|
278 | json[key] = value;
|
279 | }
|
280 | });
|
281 | if (this.suiteError) {
|
282 | json.suiteError = util_1.errorToJSON(this.suiteError);
|
283 | }
|
284 | if (this.error) {
|
285 | json.error = util_1.errorToJSON(this.error);
|
286 | }
|
287 | return json;
|
288 | };
|
289 | return Test;
|
290 | }());
|
291 | exports.default = Test;
|
292 | function isTest(value) {
|
293 | return (value != null &&
|
294 | typeof value.test === 'function' &&
|
295 | typeof value.hasPassed === 'boolean');
|
296 | }
|
297 | exports.isTest = isTest;
|
298 | function isTestOptions(value) {
|
299 | return (value != null &&
|
300 | !(value instanceof Test) &&
|
301 | value.name != null &&
|
302 | value.test != null);
|
303 | }
|
304 | exports.isTestOptions = isTestOptions;
|
305 | function isTestFunction(value) {
|
306 | return typeof value === 'function';
|
307 | }
|
308 | exports.isTestFunction = isTestFunction;
|
309 | exports.SKIP = {};
|
310 | });
|
311 |
|
\ | No newline at end of file |