expect-webdriverio 2.0.0 → 2.0.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.
Files changed (43) hide show
  1. package/README.md +1 -1
  2. package/lib/addMatchers.js +48 -0
  3. package/lib/index.js +6 -0
  4. package/lib/jasmineUtils.js +205 -0
  5. package/lib/matchers/browser/toHaveTitle.js +26 -0
  6. package/lib/matchers/browser/toHaveTitleContaining.js +15 -0
  7. package/lib/matchers/browser/toHaveUrl.js +26 -0
  8. package/lib/matchers/browser/toHaveUrlContaining.js +15 -0
  9. package/lib/matchers/element/toBeClickable.js +23 -0
  10. package/lib/matchers/element/toBeDisabled.js +16 -0
  11. package/lib/matchers/element/toBeDisplayed.js +27 -0
  12. package/lib/matchers/element/toBeDisplayedInViewport.js +27 -0
  13. package/lib/matchers/element/toBeEnabled.js +16 -0
  14. package/lib/matchers/element/toBeExisting.js +32 -0
  15. package/lib/matchers/element/toBeFocused.js +16 -0
  16. package/lib/matchers/element/toBeSelected.js +22 -0
  17. package/lib/matchers/element/toHaveAttribute.js +48 -0
  18. package/lib/matchers/element/toHaveAttributeContaining.js +16 -0
  19. package/lib/matchers/element/toHaveChildren.js +47 -0
  20. package/lib/matchers/element/toHaveElementClass.js +60 -0
  21. package/lib/matchers/element/toHaveElementClassContaining.js +20 -0
  22. package/lib/matchers/element/toHaveElementProperty.js +52 -0
  23. package/lib/matchers/element/toHaveHref.js +14 -0
  24. package/lib/matchers/element/toHaveHrefContaining.js +16 -0
  25. package/lib/matchers/element/toHaveId.js +13 -0
  26. package/lib/matchers/element/toHaveText.js +37 -0
  27. package/lib/matchers/element/toHaveTextContaining.js +15 -0
  28. package/lib/matchers/element/toHaveValue.js +13 -0
  29. package/lib/matchers/element/toHaveValueContaining.js +15 -0
  30. package/lib/matchers/elements/toBeElementsArrayOfSize.js +41 -0
  31. package/lib/matchers/mock/toBeRequested.js +12 -0
  32. package/lib/matchers/mock/toBeRequestedTimes.js +37 -0
  33. package/lib/matchers/mock/toBeRequestedWith.js +218 -0
  34. package/lib/matchers/mock/toBeRequestedWithResponse.js +13 -0
  35. package/lib/matchers.js +40 -0
  36. package/lib/options.js +33 -0
  37. package/lib/util/elementsUtil.js +26 -0
  38. package/lib/util/executeCommand.js +31 -0
  39. package/lib/util/expectAdapter.js +39 -0
  40. package/lib/util/formatMessage.js +87 -0
  41. package/lib/util/refetchElements.js +15 -0
  42. package/lib/utils.js +131 -0
  43. package/package.json +1 -1
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateElementsArray = exports.wrapExpectedWithArray = void 0;
4
+ const wrapExpectedWithArray = (el, actual, expected) => {
5
+ if (Array.isArray(el) && el.length > 1 && Array.isArray(actual)) {
6
+ expected = [expected];
7
+ }
8
+ return expected;
9
+ };
10
+ exports.wrapExpectedWithArray = wrapExpectedWithArray;
11
+ const updateElementsArray = (success, received, refetched, full = false) => {
12
+ if (!success) {
13
+ return;
14
+ }
15
+ if (Array.isArray(received) && Array.isArray(refetched)) {
16
+ if (full === true) {
17
+ while (received.length > 0) {
18
+ received.pop();
19
+ }
20
+ }
21
+ if (received.length === 0) {
22
+ refetched.forEach(el => received.push(el));
23
+ }
24
+ }
25
+ };
26
+ exports.updateElementsArray = updateElementsArray;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeCommand = void 0;
4
+ const refetchElements_1 = require("./refetchElements");
5
+ async function executeCommand(el, condition, options = {}, params = [], fullRefetch = false) {
6
+ const { isNot = false } = this;
7
+ let elements;
8
+ if (Array.isArray(el)) {
9
+ elements = await refetchElements_1.refetchElements(el, options.wait, fullRefetch);
10
+ }
11
+ else {
12
+ elements = [el];
13
+ }
14
+ if (elements.length === 0) {
15
+ return {
16
+ el: elements,
17
+ success: false,
18
+ };
19
+ }
20
+ const results = [];
21
+ for (const element of elements) {
22
+ results.push(await condition(element, ...params, options));
23
+ }
24
+ const values = [...new Set(results.filter(result => result.result === isNot).map(result => result.value))];
25
+ return {
26
+ el: Array.isArray(el) ? elements : el,
27
+ success: results.every(result => result.result === true),
28
+ values: values.length > 1 ? values : values[0]
29
+ };
30
+ }
31
+ exports.executeCommand = executeCommand;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runExpect = exports.jestResultToJasmine = exports.buildJasmineFromJestResult = exports.getContext = void 0;
4
+ const options_1 = require("../options");
5
+ const config = options_1.getConfig();
6
+ const { mode: MODE } = config;
7
+ const getContext = (context) => global === context ? {} : context || {};
8
+ exports.getContext = getContext;
9
+ function runJestExpect(fn, args) {
10
+ return fn.apply(this, args);
11
+ }
12
+ const buildJasmineFromJestResult = (result, isNot) => {
13
+ return {
14
+ pass: result.pass !== isNot,
15
+ message: result.message()
16
+ };
17
+ };
18
+ exports.buildJasmineFromJestResult = buildJasmineFromJestResult;
19
+ const jestResultToJasmine = (result, isNot) => {
20
+ if (result instanceof Promise) {
21
+ return result.then(jestStyleResult => exports.buildJasmineFromJestResult(jestStyleResult, isNot));
22
+ }
23
+ return exports.buildJasmineFromJestResult(result, isNot);
24
+ };
25
+ exports.jestResultToJasmine = jestResultToJasmine;
26
+ function runJasmineExpect(fn) {
27
+ const context = exports.getContext(this);
28
+ return {
29
+ compare(...args) {
30
+ const result = fn.apply({ ...context, isNot: false }, args);
31
+ return exports.jestResultToJasmine(result, false);
32
+ },
33
+ negativeCompare(...args) {
34
+ const result = fn.apply({ ...context, isNot: true }, args);
35
+ return exports.jestResultToJasmine(result, true);
36
+ }
37
+ };
38
+ }
39
+ exports.runExpect = MODE === 'jasmine' ? runJasmineExpect : runJestExpect;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.numberError = exports.enhanceErrorBe = exports.enhanceError = exports.not = exports.getSelectors = exports.getSelector = void 0;
4
+ const jest_matcher_utils_1 = require("jest-matcher-utils");
5
+ const jasmineUtils_1 = require("../jasmineUtils");
6
+ const EXPECTED_LABEL = 'Expected';
7
+ const RECEIVED_LABEL = 'Received';
8
+ const NOT_SUFFIX = ' [not]';
9
+ const NOT_EXPECTED_LABEL = EXPECTED_LABEL + NOT_SUFFIX;
10
+ const getSelector = (el) => {
11
+ let result = typeof el.selector === 'string' ? el.selector : '<fn>';
12
+ if (Array.isArray(el) && el.props.length > 0) {
13
+ result += ', <props>';
14
+ }
15
+ return result;
16
+ };
17
+ exports.getSelector = getSelector;
18
+ const getSelectors = (el) => {
19
+ const selectors = [];
20
+ let parent;
21
+ if (Array.isArray(el)) {
22
+ selectors.push(`${el.foundWith}(\`${exports.getSelector(el)}\`)`);
23
+ parent = el.parent;
24
+ }
25
+ else {
26
+ parent = el;
27
+ }
28
+ while (parent && 'selector' in parent) {
29
+ const selector = exports.getSelector(parent);
30
+ const index = parent.index ? `[${parent.index}]` : '';
31
+ selectors.push(`${parent.index ? '$' : ''}$(\`${selector}\`)${index}`);
32
+ parent = parent.parent;
33
+ }
34
+ return selectors.reverse().join('.');
35
+ };
36
+ exports.getSelectors = getSelectors;
37
+ const not = (isNot) => {
38
+ return `${isNot ? 'not ' : ''}`;
39
+ };
40
+ exports.not = not;
41
+ const enhanceError = (subject, expected, actual, context, verb, expectation, arg2 = '', { message = '', containing = false }) => {
42
+ const { isNot = false } = context;
43
+ subject = typeof subject === 'string' ? subject : exports.getSelectors(subject);
44
+ let contain = '';
45
+ if (containing) {
46
+ contain = ' containing';
47
+ }
48
+ if (verb) {
49
+ verb += ' ';
50
+ }
51
+ let diffString;
52
+ if (isNot && jasmineUtils_1.equals(actual, expected)) {
53
+ diffString = `${EXPECTED_LABEL}: ${jest_matcher_utils_1.printExpected(expected)}\n` +
54
+ `${RECEIVED_LABEL}: ${jest_matcher_utils_1.printReceived(actual)}`;
55
+ }
56
+ else {
57
+ diffString = jest_matcher_utils_1.printDiffOrStringify(expected, actual, EXPECTED_LABEL, RECEIVED_LABEL, true);
58
+ }
59
+ if (isNot) {
60
+ diffString = diffString
61
+ .replace(EXPECTED_LABEL, NOT_EXPECTED_LABEL)
62
+ .replace(RECEIVED_LABEL, RECEIVED_LABEL + ' '.repeat(NOT_SUFFIX.length));
63
+ }
64
+ if (message) {
65
+ message += '\n';
66
+ }
67
+ if (arg2) {
68
+ arg2 = ` ${arg2}`;
69
+ }
70
+ const msg = `${message}Expect ${subject} ${exports.not(isNot)}to ${verb}${expectation}${arg2}${contain}\n\n${diffString}`;
71
+ return msg;
72
+ };
73
+ exports.enhanceError = enhanceError;
74
+ const enhanceErrorBe = (subject, pass, context, verb, expectation, options) => {
75
+ return exports.enhanceError(subject, exports.not(context.isNot) + expectation, exports.not(!pass) + expectation, context, verb, expectation, '', options);
76
+ };
77
+ exports.enhanceErrorBe = enhanceErrorBe;
78
+ const numberError = (gte, lte, eq) => {
79
+ if (typeof eq === 'number') {
80
+ return eq;
81
+ }
82
+ let error = '';
83
+ error = `>= ${gte}`;
84
+ error += lte ? ` && <= ${lte}` : '';
85
+ return error;
86
+ };
87
+ exports.numberError = numberError;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.refetchElements = void 0;
4
+ const options_1 = require("../options");
5
+ const config = options_1.getConfig();
6
+ const { options: DEFAULT_OPTIONS } = config;
7
+ const refetchElements = async (elements, wait = DEFAULT_OPTIONS.wait, full = false) => {
8
+ if (elements) {
9
+ if (wait > 0 && (elements.length === 0 || full)) {
10
+ elements = await elements.parent[elements.foundWith](elements.selector, ...elements.props);
11
+ }
12
+ }
13
+ return elements;
14
+ };
15
+ exports.refetchElements = refetchElements;
package/lib/utils.js ADDED
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.aliasFn = exports.compareNumbers = exports.waitUntil = exports.executeCommandBe = exports.executeCommand = exports.numberError = exports.enhanceError = exports.wrapExpectedWithArray = exports.updateElementsArray = exports.compareTextWithArray = exports.compareText = void 0;
4
+ const options_1 = require("./options");
5
+ const executeCommand_1 = require("./util/executeCommand");
6
+ Object.defineProperty(exports, "executeCommand", { enumerable: true, get: function () { return executeCommand_1.executeCommand; } });
7
+ const elementsUtil_1 = require("./util/elementsUtil");
8
+ Object.defineProperty(exports, "wrapExpectedWithArray", { enumerable: true, get: function () { return elementsUtil_1.wrapExpectedWithArray; } });
9
+ Object.defineProperty(exports, "updateElementsArray", { enumerable: true, get: function () { return elementsUtil_1.updateElementsArray; } });
10
+ const formatMessage_1 = require("./util/formatMessage");
11
+ Object.defineProperty(exports, "enhanceError", { enumerable: true, get: function () { return formatMessage_1.enhanceError; } });
12
+ Object.defineProperty(exports, "numberError", { enumerable: true, get: function () { return formatMessage_1.numberError; } });
13
+ const expectAdapter_1 = require("./util/expectAdapter");
14
+ const config = options_1.getConfig();
15
+ const { options: DEFAULT_OPTIONS } = config;
16
+ const waitUntil = async (condition, isNot = false, { wait = DEFAULT_OPTIONS.wait, interval = DEFAULT_OPTIONS.interval } = {}) => {
17
+ if (wait === 0) {
18
+ return await condition();
19
+ }
20
+ try {
21
+ let error;
22
+ await browser.waitUntil(async () => {
23
+ error = undefined;
24
+ try {
25
+ return isNot !== await condition();
26
+ }
27
+ catch (err) {
28
+ error = err;
29
+ return false;
30
+ }
31
+ }, {
32
+ timeout: wait,
33
+ interval
34
+ });
35
+ if (error) {
36
+ throw error;
37
+ }
38
+ return !isNot;
39
+ }
40
+ catch (err) {
41
+ return isNot;
42
+ }
43
+ };
44
+ exports.waitUntil = waitUntil;
45
+ async function executeCommandBe(received, command, options) {
46
+ const { isNot, expectation, verb = 'be' } = this;
47
+ received = await received;
48
+ let el = received;
49
+ const pass = await waitUntil(async () => {
50
+ const result = await executeCommand_1.executeCommand.call(this, el, async (element) => ({ result: await command(element) }), options);
51
+ el = result.el;
52
+ return result.success;
53
+ }, isNot, options);
54
+ elementsUtil_1.updateElementsArray(pass, received, el);
55
+ const message = formatMessage_1.enhanceErrorBe(el, pass, this, verb, expectation, options);
56
+ return {
57
+ pass,
58
+ message: () => message
59
+ };
60
+ }
61
+ exports.executeCommandBe = executeCommandBe;
62
+ const compareNumbers = (actual, gte, lte, eq) => {
63
+ if (typeof eq === 'number') {
64
+ return actual === eq;
65
+ }
66
+ if (lte > 0 && actual > lte) {
67
+ return false;
68
+ }
69
+ return actual >= gte;
70
+ };
71
+ exports.compareNumbers = compareNumbers;
72
+ const compareText = (actual, expected, { ignoreCase = false, trim = false, containing = false }) => {
73
+ if (typeof actual !== 'string') {
74
+ return {
75
+ value: actual,
76
+ result: false
77
+ };
78
+ }
79
+ if (trim) {
80
+ actual = actual.trim();
81
+ }
82
+ if (ignoreCase) {
83
+ actual = actual.toLowerCase();
84
+ expected = expected.toLowerCase();
85
+ }
86
+ if (containing) {
87
+ return {
88
+ value: actual,
89
+ result: actual.includes(expected)
90
+ };
91
+ }
92
+ return {
93
+ value: actual,
94
+ result: actual === expected
95
+ };
96
+ };
97
+ exports.compareText = compareText;
98
+ const compareTextWithArray = (actual, expectedArray, { ignoreCase = false, trim = false, containing = false }) => {
99
+ if (typeof actual !== 'string') {
100
+ return {
101
+ value: actual,
102
+ result: false
103
+ };
104
+ }
105
+ if (trim) {
106
+ actual = actual.trim();
107
+ }
108
+ if (ignoreCase) {
109
+ actual = actual.toLowerCase();
110
+ expectedArray = expectedArray.map(item => item.toLowerCase());
111
+ }
112
+ if (containing) {
113
+ const textInArray = expectedArray.some((t) => actual.includes(t));
114
+ return {
115
+ value: actual,
116
+ result: textInArray
117
+ };
118
+ }
119
+ return {
120
+ value: actual,
121
+ result: expectedArray.includes(actual)
122
+ };
123
+ };
124
+ exports.compareTextWithArray = compareTextWithArray;
125
+ function aliasFn(fn, { verb, expectation } = {}, ...args) {
126
+ const context = expectAdapter_1.getContext(this);
127
+ context.verb = verb;
128
+ context.expectation = expectation;
129
+ return fn.apply(context, args);
130
+ }
131
+ exports.aliasFn = aliasFn;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expect-webdriverio",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {