@camperaid/watest 2.4.5 → 2.4.7

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/core/base.js CHANGED
@@ -567,6 +567,25 @@ function is_out(got, expected, msg) {
567
567
  return false;
568
568
  }
569
569
 
570
+ function throws(func, exception, msg) {
571
+ try {
572
+ func();
573
+ fail(`${msg}: no '${exception}' exception`);
574
+ } catch (e) {
575
+ is(e?.message, exception, msg);
576
+ }
577
+ }
578
+
579
+ function no_throws(func, msg) {
580
+ try {
581
+ func();
582
+ success(msg);
583
+ } catch (e) {
584
+ log_error(e);
585
+ fail(`${msg}, got: ${e?.message ?? ''} exception`);
586
+ }
587
+ }
588
+
570
589
  module.exports = {
571
590
  success,
572
591
  fail,
@@ -581,6 +600,9 @@ module.exports = {
581
600
  is_primitive,
582
601
  is_string,
583
602
 
603
+ throws,
604
+ no_throws,
605
+
584
606
  test_is,
585
607
  test_contains,
586
608
 
package/core/core.js CHANGED
@@ -231,6 +231,7 @@ module.exports = {
231
231
  success(...args) {
232
232
  return currentCore.success(...args);
233
233
  },
234
+
234
235
  failed() {
235
236
  return currentCore.failed();
236
237
  },
package/index.js CHANGED
@@ -17,6 +17,8 @@ const {
17
17
  is,
18
18
  contains,
19
19
  is_output,
20
+ no_throws,
21
+ throws,
20
22
 
21
23
  test_is,
22
24
  test_contains,
@@ -44,6 +46,7 @@ module.exports = {
44
46
  info,
45
47
  inspect,
46
48
  not_reached,
49
+ no_throws,
47
50
  ok,
48
51
  scope,
49
52
  start_session,
@@ -51,6 +54,7 @@ module.exports = {
51
54
  todo,
52
55
  test_is,
53
56
  test_contains,
57
+ throws,
54
58
  tmp_storage_dir,
55
59
  warn,
56
60
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camperaid/watest",
3
- "version": "2.4.5",
3
+ "version": "2.4.7",
4
4
  "description": "Web Application Testsuite",
5
5
  "engines": {
6
6
  "node": ">=14.15.1"
@@ -38,12 +38,12 @@
38
38
  "selenium-webdriver": "^4.0.0-beta.2"
39
39
  },
40
40
  "devDependencies": {
41
- "dotenv": "^8.2.0",
42
- "eslint": "^7.15.0",
41
+ "dotenv": "^16.0.1",
42
+ "eslint": "^8.22.0",
43
43
  "eslint-plugin-node": "^11.1.0",
44
- "husky": "^4.3.6",
45
- "lint-staged": "^10.5.3",
46
- "prettier": "2.2.1",
44
+ "husky": "^8.0.1",
45
+ "lint-staged": "^13.0.3",
46
+ "prettier": "^2.7.1",
47
47
  "prettifier": "^0.4.0"
48
48
  },
49
49
  "lint-staged": {
@@ -0,0 +1,75 @@
1
+ 'use strict';
2
+
3
+ const { is_output, throws, no_throws } = require('./test.js');
4
+
5
+ module.exports.test = async () => {
6
+ // throws: success
7
+ await is_output(
8
+ () =>
9
+ throws(
10
+ () => {
11
+ throw new Error('Error#1');
12
+ },
13
+ `Error#1`,
14
+ `Throws error#1`
15
+ ),
16
+ [`Ok: Throws error#1, got: Error#1`],
17
+ [],
18
+ `throws sucess`
19
+ );
20
+
21
+ // throws: fail, unexpected exception
22
+ await is_output(
23
+ () =>
24
+ throws(
25
+ () => {
26
+ throw new Error('Error#2');
27
+ },
28
+ `Error#1`,
29
+ `Wanted error#1`
30
+ ),
31
+ [],
32
+ [
33
+ `Failed: Wanted error#1;
34
+ got:
35
+ Error#2
36
+ expected:
37
+ Error#1
38
+ unexpected character: '2' at 6 pos, expected: '1' at '' line
39
+ `,
40
+ ],
41
+ `throws fail, unexpected exception`
42
+ );
43
+
44
+ // throws: fail, no exception
45
+ await is_output(
46
+ () => throws(() => {}, `Error#1`, `Wanted error#1`),
47
+ [],
48
+ [`Failed: Wanted error#1: no 'Error#1' exception`],
49
+ `throws fail, no exception`
50
+ );
51
+
52
+ // no_throws(() => {}, `No exceptions`)
53
+
54
+ // no_throws: success
55
+ await is_output(
56
+ () => no_throws(() => {}, `No exceptions`),
57
+ [`Ok: No exceptions`],
58
+ [],
59
+ `no throws: sucess`
60
+ );
61
+
62
+ // no_throws: fail
63
+ await is_output(
64
+ () =>
65
+ no_throws(() => {
66
+ throw new Error('Error#1');
67
+ }, `No exceptions`),
68
+ [],
69
+ [
70
+ v => v.startsWith('Error: Error#1'),
71
+ `Failed: No exceptions, got: Error#1 exception`,
72
+ ],
73
+ `no_throws fail`
74
+ );
75
+ };
@@ -8,6 +8,8 @@ const {
8
8
  success,
9
9
  } = require('../test.js');
10
10
 
11
+ const { webdrivers } = require('../../../core/settings.js');
12
+
11
13
  const completed_in = name => got => got.startsWith(`>${name} completed in`);
12
14
 
13
15
  module.exports.test = async () => {
@@ -54,94 +56,112 @@ module.exports.test = async () => {
54
56
  LogPipe.restoreStdStreams();
55
57
  }
56
58
 
57
- const buffers = LogPipe.FileStream.getLoggingBuffers();
58
- is(
59
- buffers,
60
- [
61
- ['log', ['Testsuite: shutdown', got => got.startsWith('Elapsed:')]],
62
- [
63
- 'mac/log',
59
+ const chromeLogs = webdrivers.includes('chrome')
60
+ ? [
64
61
  [
65
- '\x1B[38;5;99mStarted\x1B[0m mac/',
66
- '\x1B[102mSuccess!\x1B[0m Total: 1',
67
- '\x1B[38;5;243mCompleted\x1B[0m mac/',
62
+ 'mac/webdriver/chrome/log',
63
+ [
64
+ '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/chrome',
65
+ '\x1B[102mmac/webdriver/chrome\x1B[0m Total: 1',
66
+ '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/chrome',
67
+ ],
68
68
  ],
69
- ],
70
- [
71
- 'mac/webdriver/log',
72
69
  [
73
- '\x1B[38;5;99mStarted\x1B[0m mac/webdriver',
74
- '\x1B[102mmac/webdriver\x1B[0m Total: 1',
75
- '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver',
70
+ 'mac/webdriver/chrome/end-to-end/log',
71
+ [
72
+ '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/chrome/end-to-end',
73
+ '\x1B[102mmac/webdriver/chrome/end-to-end\x1B[0m Total: 1',
74
+ '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/chrome/end-to-end',
75
+ ],
76
76
  ],
77
- ],
78
- [
79
- 'mac/webdriver/chrome/log',
80
77
  [
81
- '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/chrome',
82
- '\x1B[102mmac/webdriver/chrome\x1B[0m Total: 1',
83
- '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/chrome',
78
+ 'mac/webdriver/chrome/end-to-end/history/log',
79
+ [
80
+ '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/chrome/end-to-end/history',
81
+ '!Running: mac/webdriver/chrome/end-to-end/history/t_history.js, path: tests/webdriver/end-to-end/history/t_history.js',
82
+ '\x1B[31mFailed:\x1B[0m TestoFail',
83
+ '\x1B[31m>mac/webdriver/chrome/end-to-end/history/t_history.js\x1B[0m has 1 failure(s)',
84
+ completed_in(
85
+ 'mac/webdriver/chrome/end-to-end/history/t_history.js'
86
+ ),
87
+ '\x1B[41m\x1B[37m>mac/webdriver/chrome/end-to-end/history/t_history.js\x1B[0m Failure count: 1',
88
+ '\x1B[41m\x1B[37mmac/webdriver/chrome/end-to-end/history > failed\x1B[0m Passed: 0. Failed: 1',
89
+ '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/chrome/end-to-end/history',
90
+ ],
84
91
  ],
85
- ],
86
- [
87
- 'mac/webdriver/chrome/end-to-end/log',
88
92
  [
89
- '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/chrome/end-to-end',
90
- '\x1B[102mmac/webdriver/chrome/end-to-end\x1B[0m Total: 1',
91
- '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/chrome/end-to-end',
93
+ 'mac/webdriver/chrome/end-to-end/history2/log',
94
+ [
95
+ '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/chrome/end-to-end/history2',
96
+ '!Running: mac/webdriver/chrome/end-to-end/history2/t_history.js, path: tests/webdriver/end-to-end/history/t_history.js',
97
+ '\x1B[32mOk:\x1B[0m TestoOk',
98
+ completed_in(
99
+ 'mac/webdriver/chrome/end-to-end/history2/t_history.js'
100
+ ),
101
+ '\x1B[102mmac/webdriver/chrome/end-to-end/history2\x1B[0m Total: 1',
102
+ '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/chrome/end-to-end/history2',
103
+ ],
92
104
  ],
93
- ],
94
- [
95
- 'mac/webdriver/chrome/end-to-end/history/log',
105
+ ]
106
+ : [];
107
+
108
+ const firefoxLogs = webdrivers.includes('firefox')
109
+ ? [
96
110
  [
97
- '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/chrome/end-to-end/history',
98
- '!Running: mac/webdriver/chrome/end-to-end/history/t_history.js, path: tests/webdriver/end-to-end/history/t_history.js',
99
- '\x1B[31mFailed:\x1B[0m TestoFail',
100
- '\x1B[31m>mac/webdriver/chrome/end-to-end/history/t_history.js\x1B[0m has 1 failure(s)',
101
- completed_in('mac/webdriver/chrome/end-to-end/history/t_history.js'),
102
- '\x1B[41m\x1B[37m>mac/webdriver/chrome/end-to-end/history/t_history.js\x1B[0m Failure count: 1',
103
- '\x1B[41m\x1B[37mmac/webdriver/chrome/end-to-end/history > failed\x1B[0m Passed: 0. Failed: 1',
104
- '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/chrome/end-to-end/history',
111
+ 'mac/webdriver/firefox/log',
112
+ [
113
+ '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/firefox',
114
+ '\x1B[102mmac/webdriver/firefox\x1B[0m Total: 1',
115
+ '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/firefox',
116
+ ],
105
117
  ],
106
- ],
107
- [
108
- 'mac/webdriver/firefox/log',
109
118
  [
110
- '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/firefox',
111
- '\x1B[102mmac/webdriver/firefox\x1B[0m Total: 1',
112
- '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/firefox',
119
+ 'mac/webdriver/firefox/end-to-end/log',
120
+ [
121
+ '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/firefox/end-to-end',
122
+ '\x1B[102mmac/webdriver/firefox/end-to-end\x1B[0m Total: 1',
123
+ '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/firefox/end-to-end',
124
+ ],
113
125
  ],
114
- ],
115
- [
116
- 'mac/webdriver/firefox/end-to-end/log',
117
126
  [
118
- '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/firefox/end-to-end',
119
- '\x1B[102mmac/webdriver/firefox/end-to-end\x1B[0m Total: 1',
120
- '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/firefox/end-to-end',
127
+ 'mac/webdriver/firefox/end-to-end/history/log',
128
+ [
129
+ '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/firefox/end-to-end/history',
130
+ '!Running: mac/webdriver/firefox/end-to-end/history/t_history.js, path: tests/webdriver/end-to-end/history/t_history.js',
131
+ '\x1B[32mOk:\x1B[0m TestoOk',
132
+ completed_in(
133
+ 'mac/webdriver/firefox/end-to-end/history/t_history.js'
134
+ ),
135
+ '\x1B[102mmac/webdriver/firefox/end-to-end/history\x1B[0m Total: 1',
136
+ '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/firefox/end-to-end/history',
137
+ ],
121
138
  ],
122
- ],
139
+ ]
140
+ : [];
141
+
142
+ const buffers = LogPipe.FileStream.getLoggingBuffers();
143
+ is(
144
+ buffers,
145
+ [
146
+ ['log', ['Testsuite: shutdown', got => got.startsWith('Elapsed:')]],
123
147
  [
124
- 'mac/webdriver/firefox/end-to-end/history/log',
148
+ 'mac/log',
125
149
  [
126
- '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/firefox/end-to-end/history',
127
- '!Running: mac/webdriver/firefox/end-to-end/history/t_history.js, path: tests/webdriver/end-to-end/history/t_history.js',
128
- '\x1B[32mOk:\x1B[0m TestoOk',
129
- completed_in('mac/webdriver/firefox/end-to-end/history/t_history.js'),
130
- '\x1B[102mmac/webdriver/firefox/end-to-end/history\x1B[0m Total: 1',
131
- '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/firefox/end-to-end/history',
150
+ '\x1B[38;5;99mStarted\x1B[0m mac/',
151
+ '\x1B[102mSuccess!\x1B[0m Total: 1',
152
+ '\x1B[38;5;243mCompleted\x1B[0m mac/',
132
153
  ],
133
154
  ],
134
155
  [
135
- 'mac/webdriver/chrome/end-to-end/history2/log',
156
+ 'mac/webdriver/log',
136
157
  [
137
- '\x1B[38;5;99mStarted\x1B[0m mac/webdriver/chrome/end-to-end/history2',
138
- '!Running: mac/webdriver/chrome/end-to-end/history2/t_history.js, path: tests/webdriver/end-to-end/history/t_history.js',
139
- '\x1B[32mOk:\x1B[0m TestoOk',
140
- completed_in('mac/webdriver/chrome/end-to-end/history2/t_history.js'),
141
- '\x1B[102mmac/webdriver/chrome/end-to-end/history2\x1B[0m Total: 1',
142
- '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver/chrome/end-to-end/history2',
158
+ '\x1B[38;5;99mStarted\x1B[0m mac/webdriver',
159
+ '\x1B[102mmac/webdriver\x1B[0m Total: 1',
160
+ '\x1B[38;5;243mCompleted\x1B[0m mac/webdriver',
143
161
  ],
144
162
  ],
163
+ ...chromeLogs,
164
+ ...firefoxLogs,
145
165
  ],
146
166
  'logging verify'
147
167
  );
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const { AppDriver, is_ok_output, do_self_tests } = require('./test.js');
3
+ const { AppDriver, do_self_tests, is_ok_output } = require('./test.js');
4
4
 
5
5
  const snippet = `
6
6
  <html><body>
@@ -46,10 +46,12 @@ module.exports.test = do_self_tests(snippet, async session => {
46
46
  `Action: Get Input`,
47
47
  `Test: Input is shown. Selector: '#input'`,
48
48
  `Ok: '#input' has to be unique, got: 1`,
49
+ `[INFO] console-api 2:32 "[WatestAction] Get Input"`,
49
50
  `Ok: Input is shown`,
50
51
  `Action: Input.type 'hello' into Type hello`,
51
52
  `Test: Focus. Selector: '#input'`,
52
53
  `Ok: '#input' has to be unique, got: 1`,
54
+ `[INFO] console-api 2:32 "[WatestAction] Input.type 'hello' into Type hello"`,
53
55
  `Ok: Focus`,
54
56
  `Test: Focused. Selector: '#input'`,
55
57
  `Ok: '#input' has to be unique, got: 1`,
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ const { do_self_tests, is_ok_output } = require('./test.js');
4
+
5
+ const snippet = `
6
+ <html><body>
7
+ <input id='input' value='hey'>
8
+ </body></html>
9
+ `;
10
+
11
+ module.exports.test = do_self_tests(snippet, async ({ driver }) => {
12
+ // ifHasElements: true path
13
+ await is_ok_output(
14
+ () =>
15
+ driver.ifHasElements(
16
+ '#input',
17
+ `ifHasElements true path`,
18
+ () => console.log(`Input doesn't exist`),
19
+ () => console.log(`Input unexpectedly exists`)
20
+ ),
21
+ [
22
+ `Test: ifHasElements true path. Selector: '#input'`,
23
+ `Input doesn't exist`,
24
+ `Ok: ifHasElements true path`,
25
+ ],
26
+ [],
27
+ `ifHasElements: true path`
28
+ );
29
+
30
+ // ifHasElements: false path
31
+ await is_ok_output(
32
+ () =>
33
+ driver.ifHasElements(
34
+ '#input-doesnot-exist',
35
+ `ifHasElements false path`,
36
+ () => console.log(`Input unexpectedly doesn't exist`),
37
+ () => console.log(`Input exists`)
38
+ ),
39
+ [
40
+ `Test: ifHasElements false path. Selector: '#input-doesnot-exist'`,
41
+ `Input exists`,
42
+ `Ok: ifHasElements false path`,
43
+ ],
44
+ [],
45
+ `ifHasElements: false path`
46
+ );
47
+ });
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ const { do_self_tests, is_ok_output } = require('./test.js');
4
+
5
+ const snippet = `
6
+ <html><body>
7
+ <input id='input' value='hey'>
8
+ </body></html>
9
+ `;
10
+
11
+ module.exports.test = do_self_tests(snippet, async ({ driver }) => {
12
+ // ifNoElements: true path
13
+ await is_ok_output(
14
+ () =>
15
+ driver.ifNoElements(
16
+ '#input-doesnot-exist',
17
+ `ifNoElements true path`,
18
+ () => console.log(`Input doesn't exist`),
19
+ () => console.log(`Input unexpectedly exists`)
20
+ ),
21
+ [
22
+ `Test: ifNoElements true path. Selector: '#input-doesnot-exist'`,
23
+ `Input doesn't exist`,
24
+ `Ok: ifNoElements true path`,
25
+ ],
26
+ [],
27
+ `ifNoElements: true path`
28
+ );
29
+
30
+ // ifNoElements: false path
31
+ await is_ok_output(
32
+ () =>
33
+ driver.ifNoElements(
34
+ '#input',
35
+ `ifNoElements false path`,
36
+ () => console.log(`Input unexpectedly doesn't exist`),
37
+ () => console.log(`Input exists`)
38
+ ),
39
+ [
40
+ `Test: ifNoElements false path. Selector: '#input'`,
41
+ `Input exists`,
42
+ `Ok: ifNoElements false path`,
43
+ ],
44
+ [],
45
+ `ifNoElements: false path`
46
+ );
47
+ });
@@ -119,8 +119,16 @@ class AppDriver {
119
119
 
120
120
  execute(script, descr) {
121
121
  return this.chain(() =>
122
- this.action(`${this.uiname}.execute ${descr}`)
123
- .executeScript(script, `Execute script`)
122
+ this.action(`${this.uiname}.execute ${descr}`).executeScript(
123
+ script,
124
+ `Execute script`
125
+ )
126
+ );
127
+ }
128
+
129
+ screenshot(msg) {
130
+ return this.chain(() =>
131
+ this.action(`${this.uiname}.screenshot for ${msg}`).screenshot()
124
132
  );
125
133
  }
126
134
 
@@ -112,6 +112,15 @@ class Driver extends DriverBase {
112
112
  return this.chain(() => action());
113
113
  }
114
114
 
115
+ /**
116
+ * Logs a message into the web console.
117
+ */
118
+ logIntoConsole(message) {
119
+ return this.chain(() =>
120
+ this.dvr.executeScript(`console.log(arguments[0])`, message)
121
+ );
122
+ }
123
+
115
124
  /**
116
125
  * Sleeps for given amount of seconds.
117
126
  */
@@ -523,16 +532,6 @@ class Driver extends DriverBase {
523
532
  );
524
533
  }
525
534
 
526
- /**
527
- * Invokes a data request to the server on client.
528
- */
529
- invokeRequest(request) {
530
- return this.executeScript(
531
- `window.DataRequest.request(${JSON.stringify(request)})`,
532
- `Invoke request: ${stringify(request)}`
533
- );
534
- }
535
-
536
535
  /**
537
536
  * Waits until script retval is matched an expected value.
538
537
  */
@@ -1082,6 +1081,30 @@ else {
1082
1081
  .then(tag => `Active element: ${tag}`)
1083
1082
  );
1084
1083
  }
1084
+
1085
+ ifHasElements(selector, msg, chain, else_chain) {
1086
+ return this.run(
1087
+ () =>
1088
+ this.dvr
1089
+ .findElements(By.css(selector))
1090
+ .then(els => (els.length > 0 ? chain() : else_chain && else_chain())),
1091
+ msg,
1092
+ `Selector: '${selector}'`
1093
+ );
1094
+ }
1095
+
1096
+ ifNoElements(selector, msg, chain, else_chain) {
1097
+ return this.run(
1098
+ () =>
1099
+ this.dvr
1100
+ .findElements(By.css(selector))
1101
+ .then(els =>
1102
+ els.length == 0 ? chain() : else_chain && else_chain()
1103
+ ),
1104
+ msg,
1105
+ `Selector: '${selector}'`
1106
+ );
1107
+ }
1085
1108
  }
1086
1109
 
1087
1110
  module.exports.Driver = Driver;
@@ -404,7 +404,7 @@ class DriverBase {
404
404
  }
405
405
 
406
406
  /**
407
- * Waits for text to match a given condition for an element defined
407
+ * Waits for a match of a given condition for element(s) defined
408
408
  * by a selector.
409
409
  */
410
410
  matchBase({
@@ -566,7 +566,8 @@ class DriverBase {
566
566
 
567
567
  let checkClick = `
568
568
  console.log('[WD] Wait for lastClick promise resolved');
569
- (window.__selenium_lastClick || Promise.resolve()).then(result => {
569
+ (Promise.resolve(window.__selenium_lastClick)).then(result => {
570
+ console.log('[WD] lastClick promise was resolved');
570
571
  delete window.__selenium_clickHandler;
571
572
  delete window.__selenium_lastClick;
572
573
  delete window.__selenium_clickElRect;
@@ -123,7 +123,10 @@ async function start_session(arg1, arg2) {
123
123
  /**
124
124
  * Denotes a test action in console, a logical unit.
125
125
  */
126
- s.action = msg => s.driver.invoke(() => group(msg, 'Action'), msg);
126
+ s.action = msg =>
127
+ s.driver
128
+ .invoke(() => group(msg, 'Action'), msg)
129
+ .logIntoConsole(`[WatestAction] ${msg}`);
127
130
 
128
131
  /**
129
132
  * Invokes a command.