@camperaid/watest 2.3.7 → 2.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.watestrc.js CHANGED
@@ -18,6 +18,11 @@ const cfg = {
18
18
  */
19
19
  log_dir: process.env.WATEST_LOG_DIR,
20
20
 
21
+ /**
22
+ * If a test takes longer than the given number, the test will fail.
23
+ */
24
+ timeout: process.env.WATEST_TIMEOUT,
25
+
21
26
  /**
22
27
  * Temporary storage dir. Recreated each test run. Shall be used to store
23
28
  * files generated by tests if any.
package/core/base.js CHANGED
@@ -324,6 +324,17 @@ function is_object_impl(
324
324
  return false;
325
325
  }
326
326
 
327
+ // Date
328
+ if (got instanceof Date) {
329
+ if (got.valueOf() == expected.valueOf()) {
330
+ return true;
331
+ }
332
+ let got_str = stringify(got);
333
+ let expected_str = `expected: ${stringify(expected)}`;
334
+ fail_(`${contextmsg} unexpected value: ${got_str}, ${expected_str}`);
335
+ return false;
336
+ }
337
+
327
338
  // Convert Set and Map to Arrays.
328
339
  if (got instanceof Set) {
329
340
  got = Array.from(got.values());
@@ -537,9 +548,7 @@ function is_out(got, expected, msg) {
537
548
 
538
549
  let min = Math.min(got_i.length, exp_i.length);
539
550
  for (let j = 0; j < min; j++) {
540
- log_error(
541
- `${j}\t'${got_i[j]}'\t'${exp_i[j]}'\t${exp_i[j] == got_i[j]}`
542
- );
551
+ log_error(`${j}\t'${got_i[j]}'\t'${exp_i[j]}'\t${exp_i[j] == got_i[j]}`);
543
552
  }
544
553
 
545
554
  for (let j = min; j < got_i.length; j++) {
package/core/core.js CHANGED
@@ -57,11 +57,16 @@ class Core {
57
57
  }
58
58
 
59
59
  fail(msg) {
60
- const m = msg;
60
+ if (typeof msg == 'object') {
61
+ inspect(msg);
62
+ this.unconditional_fail('Unexpected exception');
63
+ return;
64
+ }
65
+
61
66
  for (let v of this.expectedFailures) {
62
67
  if (v.group == '*' || v.group == this.currgroup) {
63
68
  let f = v.list.find(f => f[1] == 0 || f[0] == '*');
64
- if (f && (f[0] == '*' || m.includes(f[0]))) {
69
+ if (f && (f[0] == '*' || msg.includes(f[0]))) {
65
70
  f[1]++;
66
71
  this.warn(msg);
67
72
 
@@ -78,11 +83,6 @@ class Core {
78
83
  }
79
84
  }
80
85
 
81
- if (typeof msg == 'object') {
82
- inspect(msg);
83
- msg = 'Unexpected exception';
84
- }
85
-
86
86
  this.unconditional_fail(msg);
87
87
  }
88
88
 
package/core/series.js CHANGED
@@ -637,7 +637,23 @@ class Series {
637
637
  let start_time = new Date();
638
638
  try {
639
639
  this.core.setExpectedFailures(failures_info);
640
- await func(); // execute the test
640
+
641
+ // If timeout is given then race it against the test.
642
+ if (settings.timeout) {
643
+ let kungFuDeathGripTimer = 0;
644
+ let kungFuDeathGrip = new Promise(r => {
645
+ kungFuDeathGripTimer = setTimeout(r, settings.timeout);
646
+ }).then(() =>
647
+ fail(
648
+ `Test ${name} takes longer than ${settings.timeout}ms. It's either slow or never ends.`
649
+ )
650
+ );
651
+
652
+ await Promise.race([func(), kungFuDeathGrip]);
653
+ clearTimeout(kungFuDeathGripTimer);
654
+ } else {
655
+ await func(); // execute the test
656
+ }
641
657
  } catch (e) {
642
658
  let failmsg = e;
643
659
  if (e instanceof Error) {
package/core/settings.js CHANGED
@@ -50,6 +50,10 @@ class Settings {
50
50
  return parseInt(rc.debunk_limit) || 5;
51
51
  }
52
52
 
53
+ get timeout() {
54
+ return parseInt(rc.timeout) || 0;
55
+ }
56
+
53
57
  setupTmpStorageDir() {
54
58
  if (!rc.tmp_dir) {
55
59
  console.log(`Settings: no temporary storage dir`);
package/core/util.js CHANGED
@@ -8,9 +8,7 @@ const cfg = require('./settings.js');
8
8
  * Logs object in console colored.
9
9
  */
10
10
  function inspect(obj) {
11
- log(
12
- require('util').inspect(obj, false, null, true /* enable colors */)
13
- );
11
+ log(require('util').inspect(obj, false, null, true /* enable colors */));
14
12
  }
15
13
 
16
14
  /**
@@ -31,6 +29,9 @@ function stringify(obj, traces = new Set()) {
31
29
  if (obj instanceof Array) {
32
30
  return `[${obj.map(i => stringify(i, traces)).join(', ')}]`;
33
31
  }
32
+ if (obj instanceof Date) {
33
+ return obj.toISOString();
34
+ }
34
35
  if (obj instanceof Set) {
35
36
  let values = Array.from(obj.values());
36
37
  return `Set[${values.map(i => stringify(i, traces)).join(', ')}]`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camperaid/watest",
3
- "version": "2.3.7",
3
+ "version": "2.3.8",
4
4
  "description": "Web Application Testsuite",
5
5
  "engines": {
6
6
  "node": ">=14.15.1"
@@ -27,6 +27,25 @@ module.exports.test = async () => {
27
27
  `types: Map`
28
28
  );
29
29
 
30
+ // types: Date success
31
+ await is_output(
32
+ () => is_object(new Date('2022-01-01'), new Date('2022-01-01'), 'TstMsg'),
33
+ [`Ok: TstMsg, got: 2022-01-01T00:00:00.000Z`],
34
+ [],
35
+ `types: Date sucess`
36
+ );
37
+
38
+ // types: Date failure
39
+ await is_output(
40
+ () => is_object(new Date('2022-01-01'), new Date('2023-02-02'), 'TstMsg'),
41
+ [],
42
+ [
43
+ `Failed: TstMsg: unexpected value: 2022-01-01T00:00:00.000Z, expected: 2023-02-02T00:00:00.000Z`,
44
+ `Failed: TstMsg`,
45
+ ],
46
+ `types: Date failure`
47
+ );
48
+
30
49
  // function sucess
31
50
  await is_output(
32
51
  () => is_object({ field: 'hey' }, () => true, 'TstMsg'),
@@ -21,6 +21,7 @@ module.exports.test = () => {
21
21
  is(stringify(new Set(['v1', 'v2'])), `Set['v1', 'v2']`, 'set');
22
22
  is(stringify(new Map([['key', 'value']])), `Map{key: 'value'}`, 'map');
23
23
  is(stringify(/\d+/), `/\\d+/`, 'regexp');
24
+ is(stringify(new Date('2022-01-01')), '2022-01-01T00:00:00.000Z', `Date`);
24
25
 
25
26
  // functions
26
27
  is(
@@ -6,7 +6,7 @@
6
6
  "packages": {
7
7
  "../../../..": {
8
8
  "name": "@camperaid/watest",
9
- "version": "2.3.7",
9
+ "version": "2.3.8",
10
10
  "dev": true,
11
11
  "license": "MPL",
12
12
  "dependencies": {
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "../../../..": {
18
18
  "name": "@camperaid/watest",
19
- "version": "2.3.7",
19
+ "version": "2.3.8",
20
20
  "dev": true,
21
21
  "license": "MPL",
22
22
  "dependencies": {
@@ -6,7 +6,7 @@
6
6
  "packages": {
7
7
  "../../../..": {
8
8
  "name": "@camperaid/watest",
9
- "version": "2.3.7",
9
+ "version": "2.3.8",
10
10
  "dev": true,
11
11
  "license": "MPL",
12
12
  "dependencies": {
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "../../../..": {
18
18
  "name": "@camperaid/watest",
19
- "version": "2.3.7",
19
+ "version": "2.3.8",
20
20
  "dev": true,
21
21
  "license": "MPL",
22
22
  "dependencies": {
@@ -6,7 +6,7 @@
6
6
  "packages": {
7
7
  "../../../..": {
8
8
  "name": "@camperaid/watest",
9
- "version": "2.3.7",
9
+ "version": "2.3.8",
10
10
  "dev": true,
11
11
  "license": "MPL",
12
12
  "dependencies": {
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "../../../..": {
18
18
  "name": "@camperaid/watest",
19
- "version": "2.3.7",
19
+ "version": "2.3.8",
20
20
  "dev": true,
21
21
  "license": "MPL",
22
22
  "dependencies": {
@@ -6,7 +6,7 @@
6
6
  "packages": {
7
7
  "../../../..": {
8
8
  "name": "@camperaid/watest",
9
- "version": "2.3.7",
9
+ "version": "2.3.8",
10
10
  "dev": true,
11
11
  "license": "MPL",
12
12
  "dependencies": {
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "../../../..": {
18
18
  "name": "@camperaid/watest",
19
- "version": "2.3.7",
19
+ "version": "2.3.8",
20
20
  "dev": true,
21
21
  "license": "MPL",
22
22
  "dependencies": {
@@ -6,7 +6,7 @@
6
6
  "packages": {
7
7
  "../../../..": {
8
8
  "name": "@camperaid/watest",
9
- "version": "2.3.7",
9
+ "version": "2.3.8",
10
10
  "dev": true,
11
11
  "license": "MPL",
12
12
  "dependencies": {
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "../../../..": {
15
15
  "name": "@camperaid/watest",
16
- "version": "2.3.7",
16
+ "version": "2.3.8",
17
17
  "dev": true,
18
18
  "license": "MPL",
19
19
  "dependencies": {
@@ -6,7 +6,7 @@
6
6
  "packages": {
7
7
  "../../../..": {
8
8
  "name": "@camperaid/watest",
9
- "version": "2.3.7",
9
+ "version": "2.3.8",
10
10
  "dev": true,
11
11
  "license": "MPL",
12
12
  "dependencies": {
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "../../../..": {
18
18
  "name": "@camperaid/watest",
19
- "version": "2.3.7",
19
+ "version": "2.3.8",
20
20
  "dev": true,
21
21
  "license": "MPL",
22
22
  "dependencies": {
@@ -6,7 +6,7 @@
6
6
  "packages": {
7
7
  "../../../..": {
8
8
  "name": "@camperaid/watest",
9
- "version": "2.3.7",
9
+ "version": "2.3.8",
10
10
  "dev": true,
11
11
  "license": "MPL",
12
12
  "dependencies": {
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "../../../..": {
18
18
  "name": "@camperaid/watest",
19
- "version": "2.3.7",
19
+ "version": "2.3.8",
20
20
  "dev": true,
21
21
  "license": "MPL",
22
22
  "dependencies": {
@@ -108,7 +108,7 @@ class AppDriver {
108
108
 
109
109
  uncheck(selector, field) {
110
110
  return this.chain(() =>
111
- this.action(`${this.constructor.name}.uncheck ${field}`)
111
+ this.action(`${this.uiname}.uncheck ${field}`)
112
112
  .click(selector, `Click at ${field}`)
113
113
  .hasElements(
114
114
  `${selector}:not(:checked)`,
@@ -117,6 +117,13 @@ class AppDriver {
117
117
  );
118
118
  }
119
119
 
120
+ execute(script, descr) {
121
+ return this.chain(() =>
122
+ this.action(`${this.uiname}.execute ${descr}`)
123
+ .executeScript(script, `Execute script`)
124
+ );
125
+ }
126
+
120
127
  // Returns a name for the tested class. Typically the name convension for
121
128
  // UI drivers is a test class name postixed by Driver.
122
129
  get uiname() {
@@ -169,13 +169,47 @@ class Driver extends DriverBase {
169
169
  );
170
170
  }
171
171
 
172
+ /**
173
+ * Waits untils an element defined by a selector has attribute.
174
+ */
175
+ hasAttribute(selector, attr, msg) {
176
+ assert(selector, `hasAttribute: no selector`);
177
+ assert(attr, `hasAttribute: no attr`);
178
+ assert(msg, `hasAttribute: no msg`);
179
+
180
+ return this.matchAttribute({
181
+ selector,
182
+ attr,
183
+ msg,
184
+ test: got => got !== null,
185
+ expected_stringified: stringify(null),
186
+ });
187
+ }
188
+
189
+ /**
190
+ * Waits untils an element defined by a selector has no attribute.
191
+ */
192
+ noAttribute(selector, attr, msg) {
193
+ assert(selector, `noAttribute: no selector`);
194
+ assert(attr, `noAttribute: no attr`);
195
+ assert(msg, `noAttribute: no msg`);
196
+
197
+ return this.matchAttribute({
198
+ selector,
199
+ attr,
200
+ msg,
201
+ test: got => got === null,
202
+ expected_stringified: stringify(null),
203
+ });
204
+ }
205
+
172
206
  /**
173
207
  * Waits untils an element defined by a selector has attribute of a given value.
174
208
  */
175
209
  attributeIs(selector, attr, value, msg) {
176
210
  assert(selector, `attributeIs: no selector`);
177
211
  assert(attr, `attributeIs: no attr`);
178
- assert(value != undefined, `attributeIs: no value`);
212
+ assert(value !== undefined, `attributeIs: no value`);
179
213
  assert(msg, `attributeIs: no msg`);
180
214
 
181
215
  return this.matchAttribute({