@camperaid/watest 2.3.8 → 2.4.1

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.
@@ -54,7 +54,7 @@ module.exports.test = async () => {
54
54
  {
55
55
  name: 'mac/ui',
56
56
  path: 'tests/ui/',
57
- loader: '/Users/me/projects/camperaid/watest/tests/ui/meta.mjs',
57
+ loader: v => v.endsWith('tests/ui/meta.mjs'),
58
58
  webdriver: '',
59
59
  run_in_child_process: true,
60
60
  },
@@ -0,0 +1,55 @@
1
+ 'use strict';
2
+
3
+ const { do_self_tests, is_failure_output, is_ok_output } = require('./test.js');
4
+
5
+ const snippet = `
6
+ <html><body>
7
+ <input id='input-not-visible' hidden>
8
+ <input id='input-visible' value='hey'>
9
+ </body></html>
10
+ `;
11
+
12
+ module.exports.test = do_self_tests(snippet, async ({ driver }) => {
13
+ // noElementsOrNotVisible: no elements: success
14
+ await is_ok_output(
15
+ () =>
16
+ driver.noElementsOrNotVisible(
17
+ '#input-doesnot-exist',
18
+ `noElementsOrNotVisible`
19
+ ),
20
+ [
21
+ `Test: noElementsOrNotVisible. Selector: '#input-doesnot-exist'`,
22
+ `Ok: noElementsOrNotVisible`,
23
+ ],
24
+ [],
25
+ `noElementsOrNotVisible:no elements: success`
26
+ );
27
+
28
+ // noElementsOrNotVisible: not visible: success
29
+ await is_ok_output(
30
+ () =>
31
+ driver.noElementsOrNotVisible(
32
+ '#input-not-visible',
33
+ `noElementsOrNotVisible`
34
+ ),
35
+ [
36
+ `Test: noElementsOrNotVisible. Selector: '#input-not-visible'`,
37
+ `Ok: noElementsOrNotVisible`,
38
+ ],
39
+ [],
40
+ `noElementsOrNotVisible:not visible:success`
41
+ );
42
+
43
+ // noElementsOrNotVisible: visible: failure
44
+ await is_failure_output(
45
+ driver,
46
+ () =>
47
+ driver.noElementsOrNotVisible('#input-visible', `noElementsOrNotVisible`),
48
+ [`Test: noElementsOrNotVisible. Selector: '#input-visible'`],
49
+ [
50
+ `Failed: noElementsOrNotVisible, timeout while waiting to meet criteria`,
51
+ `Failed: noElementsOrNotVisible. Failure details: Got elements count: 1, elements visibility [true], expected: not visible`,
52
+ ],
53
+ `noElementsOrNotVisible:visible:failure`
54
+ );
55
+ });
@@ -34,7 +34,8 @@ class Driver extends DriverBase {
34
34
  url = url_or_snippet;
35
35
  }
36
36
  } catch (e) {
37
- if (e.code != 'ERR_INVALID_URL') {
37
+ // Non standard Error.code may not be set to 'ERR_INVALID_URL'.
38
+ if (!(e instanceof TypeError) || !e.message.startsWith('Invalid URL')) {
38
39
  throw e;
39
40
  }
40
41
  }
@@ -485,21 +486,25 @@ class Driver extends DriverBase {
485
486
  * Picks file(s) in a file input.
486
487
  */
487
488
  pickFile(selector, path, msg) {
488
- assert(selector, `pickFile: no selector`);
489
- assert(path, `pickFile: no path`);
490
- assert(msg, `pickFile: no msg`);
491
- return this.waitForElementToInvoke(selector, el => el.sendKeys(path), msg);
489
+ return this.pickFiles(selector, [path], msg);
492
490
  }
493
491
 
494
492
  pickFiles(selector, paths, msg) {
495
493
  assert(selector, `pickFiles: no selector`);
496
494
  assert(paths, `pickFiles: no paths`);
497
495
  assert(msg, `pickFiles: no msg`);
498
- return this.waitForElementToInvoke(
499
- selector,
500
- el => el.sendKeys(paths.join('\n')),
501
- msg
502
- );
496
+
497
+ return this.chain(async () => {
498
+ // Clear previosly set value if any.
499
+ await this.setProperty(selector, 'value', '', msg);
500
+
501
+ // Send keys to upload files.
502
+ await this.waitForElementToInvoke(
503
+ selector,
504
+ el => el.sendKeys(paths.join('\n')),
505
+ msg
506
+ );
507
+ });
503
508
  }
504
509
 
505
510
  //
@@ -929,6 +934,39 @@ else {
929
934
  return this.elementsCount(selector, 0, msg);
930
935
  }
931
936
 
937
+ /**
938
+ * Waits until no elements in DOM or no elements is visible.
939
+ */
940
+ noElementsOrNotVisible(selector, msg) {
941
+ assert(selector, `noElementsOrNotVisible: no selector`);
942
+ assert(msg, `noElementsOrNotVisible: no msg`);
943
+
944
+ let breadcrumbs = '';
945
+ let cond = new Condition(`until no elements or not visible`, async () => {
946
+ let els = await this.dvr.findElements(By.css(selector));
947
+ breadcrumbs = `Got elements count: ${els.length}, expected 0`;
948
+ if (els.length == 0) {
949
+ return true;
950
+ }
951
+ let isDisplayedArray = await Promise.all(
952
+ Array.from(els).map(el => el.isDisplayed())
953
+ );
954
+ breadcrumbs = `Got elements count: ${
955
+ els.length
956
+ }, elements visibility [${isDisplayedArray.join(
957
+ ' ,'
958
+ )}], expected: not visible`;
959
+ return isDisplayedArray.every(isDisplayed => !isDisplayed);
960
+ });
961
+
962
+ return this.run(
963
+ () => this.waitForCondition(cond, () => breadcrumbs),
964
+ msg,
965
+ `Selector: '${selector}'`,
966
+ () => breadcrumbs
967
+ );
968
+ }
969
+
932
970
  /**
933
971
  * Waits until elements count is not zero.
934
972
  */
@@ -65,6 +65,26 @@ function warn_if_stale(e, msg) {
65
65
 
66
66
  class TestExecutionError extends Error {}
67
67
 
68
+ class CriteriaTimeoutError extends Error {
69
+ constructor() {
70
+ super(`timeout while waiting to meet criteria`);
71
+ }
72
+ }
73
+
74
+ class NoElementsError extends Error {
75
+ constructor(selector) {
76
+ super(`no elements matching '${selector}' selector`);
77
+ }
78
+ }
79
+
80
+ class UnexpectedElementCountError extends Error {
81
+ constructor(selector, gotCount, expectedCount) {
82
+ super(
83
+ `ambigious '${selector}' selector, got ${gotCount} elements, expected ${expectedCount}`
84
+ );
85
+ }
86
+ }
87
+
68
88
  /**
69
89
  * A chainable wrapper around selenium web driver, provides barebone methods
70
90
  * to build webdrivers upon.
@@ -424,15 +444,17 @@ class DriverBase {
424
444
  'Waiting for at least one element to be located'
425
445
  )
426
446
  ) {
427
- throw new Error(`no elements matching '${selector}' selector`);
447
+ throw new NoElementsError(selector);
428
448
  }
429
449
  }
430
450
  throw e;
431
451
  })
432
452
  .then(els => {
433
453
  if (els.length > count) {
434
- throw new Error(
435
- `ambigious '${selector}' selector, got ${els.length} elements, expected ${count}`
454
+ throw new UnexpectedElementCountError(
455
+ selector,
456
+ els.length,
457
+ count
436
458
  );
437
459
  }
438
460
  return els;
@@ -664,8 +686,8 @@ class DriverBase {
664
686
  e instanceof error.ScriptTimeoutError
665
687
  ) {
666
688
  this.checkBreadcrumbs(get_breadcrumbs);
667
- if (e.message.startsWith(`Waiting until meet criteria`)) {
668
- throw new Error(`timeout while waiting to meet criteria`);
689
+ if (e.message.startsWith(`Waiting until`)) {
690
+ throw new CriteriaTimeoutError();
669
691
  }
670
692
  }
671
693
  throw e;
@@ -803,9 +825,7 @@ class DriverBase {
803
825
 
804
826
  return this.chain(() =>
805
827
  Promise.resolve()
806
- .then(() =>
807
- log(`Test: ${msg}${(details && `. ${details}`) || ''}`)
808
- )
828
+ .then(() => log(`Test: ${msg}${(details && `. ${details}`) || ''}`))
809
829
  .then(() => chain())
810
830
  .then(v => this.browserLogs().then(() => v))
811
831
  .then(v => {
@@ -830,6 +850,13 @@ class DriverBase {
830
850
  }`;
831
851
  }
832
852
  report(`${msg}${fdetails}`);
853
+ if (
854
+ !(e instanceof CriteriaTimeoutError) &&
855
+ !(e instanceof NoElementsError) &&
856
+ !(e instanceof UnexpectedElementCountError)
857
+ ) {
858
+ log_error(e);
859
+ }
833
860
  })
834
861
  .then(() => this.captureScreenshot())
835
862
  .catch(e => {