@camperaid/watest 2.3.7 → 2.4.0

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
  },
@@ -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() {
@@ -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
  }
@@ -169,13 +170,47 @@ class Driver extends DriverBase {
169
170
  );
170
171
  }
171
172
 
173
+ /**
174
+ * Waits untils an element defined by a selector has attribute.
175
+ */
176
+ hasAttribute(selector, attr, msg) {
177
+ assert(selector, `hasAttribute: no selector`);
178
+ assert(attr, `hasAttribute: no attr`);
179
+ assert(msg, `hasAttribute: no msg`);
180
+
181
+ return this.matchAttribute({
182
+ selector,
183
+ attr,
184
+ msg,
185
+ test: got => got !== null,
186
+ expected_stringified: stringify(null),
187
+ });
188
+ }
189
+
190
+ /**
191
+ * Waits untils an element defined by a selector has no attribute.
192
+ */
193
+ noAttribute(selector, attr, msg) {
194
+ assert(selector, `noAttribute: no selector`);
195
+ assert(attr, `noAttribute: no attr`);
196
+ assert(msg, `noAttribute: no msg`);
197
+
198
+ return this.matchAttribute({
199
+ selector,
200
+ attr,
201
+ msg,
202
+ test: got => got === null,
203
+ expected_stringified: stringify(null),
204
+ });
205
+ }
206
+
172
207
  /**
173
208
  * Waits untils an element defined by a selector has attribute of a given value.
174
209
  */
175
210
  attributeIs(selector, attr, value, msg) {
176
211
  assert(selector, `attributeIs: no selector`);
177
212
  assert(attr, `attributeIs: no attr`);
178
- assert(value != undefined, `attributeIs: no value`);
213
+ assert(value !== undefined, `attributeIs: no value`);
179
214
  assert(msg, `attributeIs: no msg`);
180
215
 
181
216
  return this.matchAttribute({
@@ -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;
@@ -665,7 +687,7 @@ class DriverBase {
665
687
  ) {
666
688
  this.checkBreadcrumbs(get_breadcrumbs);
667
689
  if (e.message.startsWith(`Waiting until meet criteria`)) {
668
- throw new Error(`timeout while waiting to meet criteria`);
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 => {