expect-webdriverio 5.3.1 → 5.3.3

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 (81) hide show
  1. package/lib/{matchers → src/matchers}/snapshot.js +1 -1
  2. package/lib/test/__fixtures__/utils.js +19 -0
  3. package/lib/test/index.test.js +8 -0
  4. package/lib/test/matchers/beMatchers.test.js +109 -0
  5. package/lib/test/matchers/browser/toHaveClipboardText.test.js +21 -0
  6. package/lib/test/matchers/browserMatchers.test.js +102 -0
  7. package/lib/test/matchers/element/toBeDisabled.test.js +121 -0
  8. package/lib/test/matchers/element/toHaveAttribute.test.js +131 -0
  9. package/lib/test/matchers/element/toHaveChildren.test.js +62 -0
  10. package/lib/test/matchers/element/toHaveComputedLabel.test.js +284 -0
  11. package/lib/test/matchers/element/toHaveComputedRole.test.js +284 -0
  12. package/lib/test/matchers/element/toHaveElementClass.test.js +125 -0
  13. package/lib/test/matchers/element/toHaveElementProperty.test.js +111 -0
  14. package/lib/test/matchers/element/toHaveHTML.test.js +291 -0
  15. package/lib/test/matchers/element/toHaveHeight.test.js +171 -0
  16. package/lib/test/matchers/element/toHaveHref.test.js +54 -0
  17. package/lib/test/matchers/element/toHaveId.test.js +54 -0
  18. package/lib/test/matchers/element/toHaveSize.test.js +109 -0
  19. package/lib/test/matchers/element/toHaveStyle.test.js +199 -0
  20. package/lib/test/matchers/element/toHaveText.test.js +333 -0
  21. package/lib/test/matchers/element/toHaveValue.test.js +81 -0
  22. package/lib/test/matchers/element/toHaveWidth.test.js +171 -0
  23. package/lib/test/matchers/elements/toBeElementsArrayOfSize.test.js +141 -0
  24. package/lib/test/matchers/mock/toBeRequested.test.js +73 -0
  25. package/lib/test/matchers/mock/toBeRequestedTimes.test.js +108 -0
  26. package/lib/test/matchers/mock/toBeRequestedWith.test.js +343 -0
  27. package/lib/test/matchers.test.js +54 -0
  28. package/lib/test/snapshot.test.js +53 -0
  29. package/lib/test/softAssertions.test.js +332 -0
  30. package/lib/test/util/elementsUtil.test.js +18 -0
  31. package/lib/test/util/formatMessage.test.js +96 -0
  32. package/lib/test/util/refetchElements.test.js +19 -0
  33. package/lib/test/utils.test.js +117 -0
  34. package/lib/{tsconfig.build.tsbuildinfo → tsconfig.tsbuildinfo} +1 -1
  35. package/package.json +2 -2
  36. package/types/expect-webdriverio.d.ts +39 -28
  37. package/types/standalone.d.ts +2 -0
  38. /package/lib/{constants.js → src/constants.js} +0 -0
  39. /package/lib/{index.js → src/index.js} +0 -0
  40. /package/lib/{jasmineUtils.js → src/jasmineUtils.js} +0 -0
  41. /package/lib/{matchers → src/matchers}/browser/toHaveClipboardText.js +0 -0
  42. /package/lib/{matchers → src/matchers}/browser/toHaveTitle.js +0 -0
  43. /package/lib/{matchers → src/matchers}/browser/toHaveUrl.js +0 -0
  44. /package/lib/{matchers → src/matchers}/element/toBeClickable.js +0 -0
  45. /package/lib/{matchers → src/matchers}/element/toBeDisabled.js +0 -0
  46. /package/lib/{matchers → src/matchers}/element/toBeDisplayed.js +0 -0
  47. /package/lib/{matchers → src/matchers}/element/toBeDisplayedInViewport.js +0 -0
  48. /package/lib/{matchers → src/matchers}/element/toBeEnabled.js +0 -0
  49. /package/lib/{matchers → src/matchers}/element/toBeExisting.js +0 -0
  50. /package/lib/{matchers → src/matchers}/element/toBeFocused.js +0 -0
  51. /package/lib/{matchers → src/matchers}/element/toBeSelected.js +0 -0
  52. /package/lib/{matchers → src/matchers}/element/toHaveAttribute.js +0 -0
  53. /package/lib/{matchers → src/matchers}/element/toHaveChildren.js +0 -0
  54. /package/lib/{matchers → src/matchers}/element/toHaveClass.js +0 -0
  55. /package/lib/{matchers → src/matchers}/element/toHaveComputedLabel.js +0 -0
  56. /package/lib/{matchers → src/matchers}/element/toHaveComputedRole.js +0 -0
  57. /package/lib/{matchers → src/matchers}/element/toHaveElementProperty.js +0 -0
  58. /package/lib/{matchers → src/matchers}/element/toHaveHTML.js +0 -0
  59. /package/lib/{matchers → src/matchers}/element/toHaveHeight.js +0 -0
  60. /package/lib/{matchers → src/matchers}/element/toHaveHref.js +0 -0
  61. /package/lib/{matchers → src/matchers}/element/toHaveId.js +0 -0
  62. /package/lib/{matchers → src/matchers}/element/toHaveSize.js +0 -0
  63. /package/lib/{matchers → src/matchers}/element/toHaveStyle.js +0 -0
  64. /package/lib/{matchers → src/matchers}/element/toHaveText.js +0 -0
  65. /package/lib/{matchers → src/matchers}/element/toHaveValue.js +0 -0
  66. /package/lib/{matchers → src/matchers}/element/toHaveWidth.js +0 -0
  67. /package/lib/{matchers → src/matchers}/elements/toBeElementsArrayOfSize.js +0 -0
  68. /package/lib/{matchers → src/matchers}/mock/toBeRequested.js +0 -0
  69. /package/lib/{matchers → src/matchers}/mock/toBeRequestedTimes.js +0 -0
  70. /package/lib/{matchers → src/matchers}/mock/toBeRequestedWith.js +0 -0
  71. /package/lib/{matchers.js → src/matchers.js} +0 -0
  72. /package/lib/{snapshot.js → src/snapshot.js} +0 -0
  73. /package/lib/{softAssert.js → src/softAssert.js} +0 -0
  74. /package/lib/{softAssertService.js → src/softAssertService.js} +0 -0
  75. /package/lib/{softExpect.js → src/softExpect.js} +0 -0
  76. /package/lib/{types.js → src/types.js} +0 -0
  77. /package/lib/{util → src/util}/elementsUtil.js +0 -0
  78. /package/lib/{util → src/util}/executeCommand.js +0 -0
  79. /package/lib/{util → src/util}/formatMessage.js +0 -0
  80. /package/lib/{util → src/util}/refetchElements.js +0 -0
  81. /package/lib/{utils.js → src/utils.js} +0 -0
@@ -76,7 +76,7 @@ export function toMatchInlineSnapshot(received, inlineSnapshot, message) {
76
76
  }
77
77
  const trace = error.stack?.split('\n').filter((line) => (line.includes('__INLINE_SNAPSHOT__') ||
78
78
  !(line.includes('__EXTERNAL_MATCHER_TRAP__') ||
79
- line.includes(`expect-webdriverio${path.sep}lib${path.sep}matchers${path.sep}snapshot.js:`)))) || [];
79
+ line.includes(`expect-webdriverio${path.sep}lib${path.sep}matchers${path.sep}snapshot.js:`)))).filter((line) => (!line.includes('node_modules/jasmine-core/'))) || [];
80
80
  if (process.env.WDIO_INTERNAL_TEST) {
81
81
  trace.splice(2, 1);
82
82
  }
@@ -0,0 +1,19 @@
1
+ export function matcherNameToString(matcherName) {
2
+ return matcherName.replace(/([A-Z])/g, ' $1').toLowerCase();
3
+ }
4
+ export function getExpectMessage(msg) {
5
+ return msg.split('\n')[0];
6
+ }
7
+ export function getExpected(msg) {
8
+ return getReceivedOrExpected(msg, 'Expected');
9
+ }
10
+ export function getReceived(msg) {
11
+ return getReceivedOrExpected(msg, 'Received');
12
+ }
13
+ function getReceivedOrExpected(msg, type) {
14
+ return msg.split('\n').find((line, idx) => idx > 1 && line.startsWith(type));
15
+ }
16
+ export function removeColors(msg) {
17
+ const s = msg.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '');
18
+ return s;
19
+ }
@@ -0,0 +1,8 @@
1
+ import { test, expect } from 'vitest';
2
+ import { setOptions, expect as expectExport, matchers, utils } from '../src/index.js';
3
+ test('index', () => {
4
+ expect(setOptions.name).toBe('setDefaultOptions');
5
+ expect(expectExport).toBeDefined();
6
+ expect(utils.compareText).toBeDefined();
7
+ expect(matchers.size).toEqual(41);
8
+ });
@@ -0,0 +1,109 @@
1
+ import { vi, test, describe, expect } from 'vitest';
2
+ import { $ } from '@wdio/globals';
3
+ import { getExpectMessage, getReceived, matcherNameToString } from '../__fixtures__/utils.js';
4
+ import * as Matchers from '../../src/matchers.js';
5
+ vi.mock('@wdio/globals');
6
+ const ignoredMatchers = ['toBeElementsArrayOfSize', 'toBeDisabled', 'toBeRequested', 'toBeRequestedTimes', 'toBeRequestedWithResponse', 'toBeRequestedWith'];
7
+ const beMatchers = [
8
+ ...Object.keys(Matchers).filter(name => name.startsWith('toBe') && !ignoredMatchers.includes(name)),
9
+ 'toExist'
10
+ ];
11
+ describe('be* matchers', () => {
12
+ beMatchers.forEach((name) => {
13
+ const fn = Matchers[name];
14
+ describe(name, () => {
15
+ test('wait for success', async () => {
16
+ const el = await $('sel');
17
+ el._attempts = 2;
18
+ el._value = function () {
19
+ if (this._attempts > 0) {
20
+ this._attempts--;
21
+ return false;
22
+ }
23
+ return true;
24
+ };
25
+ const result = await fn.call({}, el);
26
+ expect(result.pass).toBe(true);
27
+ expect(el._attempts).toBe(0);
28
+ });
29
+ test('wait but failure', async () => {
30
+ const el = await $('sel');
31
+ el._value = function () {
32
+ throw new Error('some error');
33
+ };
34
+ await expect(() => fn.call({}, el, 10, {}))
35
+ .rejects.toThrow('some error');
36
+ });
37
+ test('success on the first attempt', async () => {
38
+ const el = await $('sel');
39
+ el._attempts = 0;
40
+ el._value = function () {
41
+ this._attempts++;
42
+ return true;
43
+ };
44
+ const result = await fn.call({}, el);
45
+ expect(result.pass).toBe(true);
46
+ expect(el._attempts).toBe(1);
47
+ });
48
+ test('no wait - failure', async () => {
49
+ const el = await $('sel');
50
+ el._attempts = 0;
51
+ el._value = function () {
52
+ this._attempts++;
53
+ return false;
54
+ };
55
+ const result = await fn.call({}, el, { wait: 0 });
56
+ expect(result.pass).toBe(false);
57
+ expect(el._attempts).toBe(1);
58
+ });
59
+ test('no wait - success', async () => {
60
+ const el = await $('sel');
61
+ el._attempts = 0;
62
+ el._value = function () {
63
+ this._attempts++;
64
+ return true;
65
+ };
66
+ const result = await fn.call({}, el, { wait: 0 });
67
+ expect(result.pass).toBe(true);
68
+ expect(el._attempts).toBe(1);
69
+ });
70
+ test('not - failure', async () => {
71
+ const result = await fn.call({ isNot: true }, $('sel'), { wait: 0 });
72
+ const received = getReceived(result.message());
73
+ expect(received).not.toContain('not');
74
+ expect(result.pass).toBe(true);
75
+ });
76
+ test('not - success', async () => {
77
+ const el = await $('sel');
78
+ el._value = function () {
79
+ return false;
80
+ };
81
+ const result = await fn.call({ isNot: true }, el, { wait: 0 });
82
+ const received = getReceived(result.message());
83
+ expect(received).toContain('not');
84
+ expect(result.pass).toBe(false);
85
+ });
86
+ test('not - failure (with wait)', async () => {
87
+ const result = await fn.call({ isNot: true }, $('sel'), { wait: 1 });
88
+ const received = getReceived(result.message());
89
+ expect(received).not.toContain('not');
90
+ expect(result.pass).toBe(true);
91
+ });
92
+ test('not - success (with wait)', async () => {
93
+ const el = await $('sel');
94
+ el._value = function () {
95
+ return false;
96
+ };
97
+ const result = await fn.call({ isNot: true }, el, { wait: 1 });
98
+ const received = getReceived(result.message());
99
+ expect(received).toContain('not');
100
+ expect(result.pass).toBe(false);
101
+ });
102
+ test('message', async () => {
103
+ const result = await fn.call({}, $('sel'));
104
+ expect(getExpectMessage(result.message()))
105
+ .toContain(matcherNameToString(name));
106
+ });
107
+ });
108
+ });
109
+ });
@@ -0,0 +1,21 @@
1
+ import { vi, test, expect } from 'vitest';
2
+ import { browser } from '@wdio/globals';
3
+ import { toHaveClipboardText } from '../../../src/matchers/browser/toHaveClipboardText.js';
4
+ vi.mock('@wdio/globals');
5
+ const beforeAssertion = vi.fn();
6
+ const afterAssertion = vi.fn();
7
+ test('toHaveClipboardText', async () => {
8
+ const result = await toHaveClipboardText.call({}, browser, 'some ClipBoard text', { ignoreCase: true, beforeAssertion, afterAssertion });
9
+ expect(result.pass).toBe(true);
10
+ expect(beforeAssertion).toBeCalledWith({
11
+ matcherName: 'toHaveClipboardText',
12
+ expectedValue: 'some ClipBoard text',
13
+ options: { ignoreCase: true, beforeAssertion, afterAssertion }
14
+ });
15
+ expect(afterAssertion).toBeCalledWith({
16
+ matcherName: 'toHaveClipboardText',
17
+ expectedValue: 'some ClipBoard text',
18
+ options: { ignoreCase: true, beforeAssertion, afterAssertion },
19
+ result
20
+ });
21
+ });
@@ -0,0 +1,102 @@
1
+ import { vi, test, describe, expect } from 'vitest';
2
+ import { browser } from '@wdio/globals';
3
+ import { getExpectMessage, getReceived, matcherNameToString, getExpected } from '../__fixtures__/utils.js';
4
+ import * as Matchers from '../../src/matchers.js';
5
+ vi.mock('@wdio/globals');
6
+ const browserMatchers = ['toHaveUrl', 'toHaveTitle'];
7
+ const validText = ' Valid Text ';
8
+ const wrongText = ' Wrong Text ';
9
+ describe('browser matchers', () => {
10
+ browserMatchers.forEach((name) => {
11
+ const fn = Matchers[name];
12
+ describe(name, () => {
13
+ test('wait for success', async () => {
14
+ browser._attempts = 2;
15
+ browser._value = function () {
16
+ if (this._attempts > 0) {
17
+ this._attempts--;
18
+ return wrongText;
19
+ }
20
+ return validText;
21
+ };
22
+ const result = await fn.call({}, browser, validText, { trim: false });
23
+ expect(result.pass).toBe(true);
24
+ expect(browser._attempts).toBe(0);
25
+ });
26
+ test('wait but failure', async () => {
27
+ browser._value = function () {
28
+ throw new Error('some error');
29
+ };
30
+ await expect(() => fn.call({}, browser, validText, { trim: false }))
31
+ .rejects.toThrow('some error');
32
+ });
33
+ test('success on the first attempt', async () => {
34
+ browser._attempts = 0;
35
+ browser._value = function () {
36
+ this._attempts++;
37
+ return validText;
38
+ };
39
+ const result = await fn.call({}, browser, validText, { trim: false });
40
+ expect(result.pass).toBe(true);
41
+ expect(browser._attempts).toBe(1);
42
+ });
43
+ test('no wait - failure', async () => {
44
+ browser._attempts = 0;
45
+ browser._value = function () {
46
+ this._attempts++;
47
+ return wrongText;
48
+ };
49
+ const result = await fn.call({}, browser, validText, { wait: 0, trim: false });
50
+ expect(result.pass).toBe(false);
51
+ expect(browser._attempts).toBe(1);
52
+ });
53
+ test('no wait - success', async () => {
54
+ browser._attempts = 0;
55
+ browser._value = function () {
56
+ this._attempts++;
57
+ return validText;
58
+ };
59
+ const result = await fn.call({}, browser, validText, { wait: 0, trim: false });
60
+ expect(result.pass).toBe(true);
61
+ expect(browser._attempts).toBe(1);
62
+ });
63
+ test('not - failure', async () => {
64
+ const result = await fn.call({ isNot: true }, browser, validText, { wait: 0, trim: false });
65
+ expect(getExpectMessage(result.message())).toContain('not');
66
+ expect(getExpected(result.message())).toContain('not');
67
+ expect(result.pass).toBe(true);
68
+ });
69
+ test('not - success', async () => {
70
+ browser._value = function () {
71
+ return wrongText;
72
+ };
73
+ const result = await fn.call({ isNot: true }, browser, validText, { wait: 0 });
74
+ expect(getExpectMessage(result.message())).toContain('not');
75
+ expect(getExpected(result.message())).toContain('Valid');
76
+ expect(getReceived(result.message())).toContain('Wrong');
77
+ expect(result.pass).toBe(false);
78
+ });
79
+ test('not - failure (with wait)', async () => {
80
+ delete browser._value;
81
+ const result = await fn.call({ isNot: true }, browser, validText, { wait: 1, trim: false });
82
+ expect(getExpectMessage(result.message())).toContain('not');
83
+ expect(getExpected(result.message())).toContain('not');
84
+ expect(result.pass).toBe(true);
85
+ });
86
+ test('not - success (with wait)', async () => {
87
+ browser._value = function () {
88
+ return wrongText;
89
+ };
90
+ const result = await fn.call({ isNot: true }, browser, validText, { wait: 1 });
91
+ expect(getExpectMessage(result.message())).toContain('not');
92
+ expect(getExpected(result.message())).toContain('Valid');
93
+ expect(getReceived(result.message())).toContain('Wrong');
94
+ expect(result.pass).toBe(false);
95
+ });
96
+ test('message', async () => {
97
+ const result = await fn.call({}, browser);
98
+ expect(getExpectMessage(result.message())).toContain(matcherNameToString(name));
99
+ });
100
+ });
101
+ });
102
+ });
@@ -0,0 +1,121 @@
1
+ import { vi, test, describe, expect } from 'vitest';
2
+ import { $ } from '@wdio/globals';
3
+ import { getExpectMessage, getReceived } from '../../__fixtures__/utils.js';
4
+ import { toBeDisabled } from '../../../src/matchers/element/toBeDisabled.js';
5
+ vi.mock('@wdio/globals');
6
+ describe('toBeDisabled', () => {
7
+ test('wait for success', async () => {
8
+ const el = await $('sel');
9
+ el._attempts = 2;
10
+ el._value = function () {
11
+ if (this._attempts > 0) {
12
+ this._attempts--;
13
+ return true;
14
+ }
15
+ return false;
16
+ };
17
+ const beforeAssertion = vi.fn();
18
+ const afterAssertion = vi.fn();
19
+ const result = await toBeDisabled.call({}, el, { beforeAssertion, afterAssertion });
20
+ expect(result.pass).toBe(true);
21
+ expect(el._attempts).toBe(0);
22
+ expect(beforeAssertion).toBeCalledWith({
23
+ matcherName: 'toBeDisabled',
24
+ options: { beforeAssertion, afterAssertion }
25
+ });
26
+ expect(afterAssertion).toBeCalledWith({
27
+ matcherName: 'toBeDisabled',
28
+ options: { beforeAssertion, afterAssertion },
29
+ result
30
+ });
31
+ });
32
+ test('wait but failure', async () => {
33
+ const el = await $('sel');
34
+ el._value = function () {
35
+ throw new Error('some error');
36
+ };
37
+ await expect(() => toBeDisabled.call({}, el))
38
+ .rejects.toThrow('some error');
39
+ });
40
+ test('success on the first attempt', async () => {
41
+ const el = await $('sel');
42
+ el._attempts = 0;
43
+ el._value = function () {
44
+ this._attempts++;
45
+ return false;
46
+ };
47
+ const result = await toBeDisabled.call({}, el);
48
+ expect(result.pass).toBe(true);
49
+ expect(el._attempts).toBe(1);
50
+ });
51
+ test('no wait - failure', async () => {
52
+ const el = await $('sel');
53
+ el._attempts = 0;
54
+ el._value = function () {
55
+ this._attempts++;
56
+ return true;
57
+ };
58
+ const result = await toBeDisabled.call({}, el, { wait: 0 });
59
+ expect(result.pass).toBe(false);
60
+ expect(el._attempts).toBe(1);
61
+ });
62
+ test('no wait - success', async () => {
63
+ const el = await $('sel');
64
+ el._attempts = 0;
65
+ el._value = function () {
66
+ this._attempts++;
67
+ return false;
68
+ };
69
+ const result = await toBeDisabled.call({}, el, { wait: 0 });
70
+ expect(result.pass).toBe(true);
71
+ expect(el._attempts).toBe(1);
72
+ });
73
+ test('not - failure', async () => {
74
+ const el = await $('sel');
75
+ el._value = function () {
76
+ return false;
77
+ };
78
+ const result = await toBeDisabled.call({ isNot: true }, el, { wait: 0 });
79
+ const received = getReceived(result.message());
80
+ expect(received).not.toContain('not');
81
+ expect(result.pass).toBe(true);
82
+ });
83
+ test('not - success', async () => {
84
+ const el = await $('sel');
85
+ el._value = function () {
86
+ return true;
87
+ };
88
+ const result = await toBeDisabled.call({ isNot: true }, el, { wait: 0 });
89
+ const received = getReceived(result.message());
90
+ expect(received).toContain('not');
91
+ expect(result.pass).toBe(false);
92
+ });
93
+ test('not - failure (with wait)', async () => {
94
+ const el = await $('sel');
95
+ el._value = function () {
96
+ return false;
97
+ };
98
+ const result = await toBeDisabled.call({ isNot: true }, el, { wait: 1 });
99
+ const received = getReceived(result.message());
100
+ expect(received).not.toContain('not');
101
+ expect(result.pass).toBe(true);
102
+ });
103
+ test('not - success (with wait)', async () => {
104
+ const el = await $('sel');
105
+ el._value = function () {
106
+ return true;
107
+ };
108
+ const result = await toBeDisabled.call({ isNot: true }, el, { wait: 1 });
109
+ const received = getReceived(result.message());
110
+ expect(received).toContain('not');
111
+ expect(result.pass).toBe(false);
112
+ });
113
+ test('message', async () => {
114
+ const el = await $('sel');
115
+ el._value = function () {
116
+ return false;
117
+ };
118
+ const result = await toBeDisabled.call({}, el);
119
+ expect(getExpectMessage(result.message())).toContain('to be disabled');
120
+ });
121
+ });
@@ -0,0 +1,131 @@
1
+ import { vi, test, describe, expect, beforeEach } from 'vitest';
2
+ import { $ } from '@wdio/globals';
3
+ import { getExpectMessage, getExpected, getReceived } from '../../__fixtures__/utils.js';
4
+ import { toHaveAttribute } from '../../../src/matchers/element/toHaveAttribute.js';
5
+ vi.mock('@wdio/globals');
6
+ describe('toHaveAttribute', () => {
7
+ let el;
8
+ beforeEach(async () => {
9
+ el = await $('sel');
10
+ });
11
+ describe('attribute exists', () => {
12
+ test('success when present', async () => {
13
+ const beforeAssertion = vi.fn();
14
+ const afterAssertion = vi.fn();
15
+ el.getAttribute = vi.fn().mockImplementation(() => {
16
+ return 'Correct Value';
17
+ });
18
+ const result = await toHaveAttribute.call({}, el, 'attribute_name', undefined, { beforeAssertion, afterAssertion });
19
+ expect(result.pass).toBe(true);
20
+ expect(beforeAssertion).toBeCalledWith({
21
+ matcherName: 'toHaveAttribute',
22
+ expectedValue: ['attribute_name', undefined],
23
+ options: { beforeAssertion, afterAssertion }
24
+ });
25
+ expect(afterAssertion).toBeCalledWith({
26
+ matcherName: 'toHaveAttribute',
27
+ expectedValue: ['attribute_name', undefined],
28
+ options: { beforeAssertion, afterAssertion },
29
+ result
30
+ });
31
+ });
32
+ test('failure when not present', async () => {
33
+ el.getAttribute = vi.fn().mockImplementation(() => {
34
+ return null;
35
+ });
36
+ const result = await toHaveAttribute.call({}, el, 'attribute_name');
37
+ expect(result.pass).toBe(false);
38
+ });
39
+ describe('message shows correctly', () => {
40
+ let result;
41
+ beforeEach(async () => {
42
+ el.getAttribute = vi.fn().mockImplementation(() => {
43
+ return null;
44
+ });
45
+ result = await toHaveAttribute.call({}, el, 'attribute_name');
46
+ });
47
+ test('expect message', () => {
48
+ expect(getExpectMessage(result.message())).toContain('to have attribute');
49
+ });
50
+ test('expected message', () => {
51
+ expect(getExpected(result.message())).toContain('true');
52
+ });
53
+ test('received message', () => {
54
+ expect(getReceived(result.message())).toContain('false');
55
+ });
56
+ });
57
+ });
58
+ describe('attribute has value', () => {
59
+ test('success with correct value', async () => {
60
+ el.getAttribute = vi.fn().mockImplementation(() => {
61
+ return 'Correct Value';
62
+ });
63
+ const result = await toHaveAttribute.call({}, el, 'attribute_name', 'Correct Value', { ignoreCase: true });
64
+ expect(result.pass).toBe(true);
65
+ });
66
+ test('success with RegExp and correct value', async () => {
67
+ el.getAttribute = vi.fn().mockImplementation(() => {
68
+ return 'Correct Value';
69
+ });
70
+ const result = await toHaveAttribute.call({}, el, 'attribute_name', /cOrReCt VaLuE/i);
71
+ expect(result.pass).toBe(true);
72
+ });
73
+ test('failure with wrong value', async () => {
74
+ el.getAttribute = vi.fn().mockImplementation(() => {
75
+ return 'Wrong Value';
76
+ });
77
+ const result = await toHaveAttribute.call({}, el, 'attribute_name', 'Correct Value', { ignoreCase: true });
78
+ expect(result.pass).toBe(false);
79
+ });
80
+ test('failure with non-string attribute value as actual', async () => {
81
+ el.getAttribute = vi.fn().mockImplementation(() => {
82
+ return 123;
83
+ });
84
+ const result = await toHaveAttribute.call({}, el, 'attribute_name', 'Correct Value', { ignoreCase: true });
85
+ expect(result.pass).toBe(false);
86
+ });
87
+ test('failure with non-string attribute value as expected', async () => {
88
+ el.getAttribute = vi.fn().mockImplementation(() => {
89
+ return 'Correct Value';
90
+ });
91
+ const result = await toHaveAttribute.call({}, el, 'attribute_name', 123, { ignoreCase: true });
92
+ expect(result.pass).toBe(false);
93
+ });
94
+ describe('message shows correctly', () => {
95
+ let result;
96
+ beforeEach(async () => {
97
+ el.getAttribute = vi.fn().mockImplementation(() => {
98
+ return 'Wrong';
99
+ });
100
+ result = await toHaveAttribute.call({}, el, 'attribute_name', 'Correct');
101
+ });
102
+ test('expect message', () => {
103
+ expect(getExpectMessage(result.message())).toContain('to have attribute');
104
+ });
105
+ test('expected message', () => {
106
+ expect(getExpected(result.message())).toContain('Correct');
107
+ });
108
+ test('received message', () => {
109
+ expect(getReceived(result.message())).toContain('Wrong');
110
+ });
111
+ });
112
+ describe('failure with RegExp, message shows correctly', () => {
113
+ let result;
114
+ beforeEach(async () => {
115
+ el.getAttribute = vi.fn().mockImplementation(() => {
116
+ return 'Wrong';
117
+ });
118
+ result = await toHaveAttribute.call({}, el, 'attribute_name', /WDIO/);
119
+ });
120
+ test('expect message', () => {
121
+ expect(getExpectMessage(result.message())).toContain('to have attribute');
122
+ });
123
+ test('expected message', () => {
124
+ expect(getExpected(result.message())).toContain('/WDIO/');
125
+ });
126
+ test('received message', () => {
127
+ expect(getReceived(result.message())).toContain('Wrong');
128
+ });
129
+ });
130
+ });
131
+ });
@@ -0,0 +1,62 @@
1
+ import { vi, test, describe, expect } from 'vitest';
2
+ import { $ } from '@wdio/globals';
3
+ import { toHaveChildren } from '../../../src/matchers/element/toHaveChildren.js';
4
+ vi.mock('@wdio/globals');
5
+ describe('toHaveChildren', () => {
6
+ test('no value', async () => {
7
+ const beforeAssertion = vi.fn();
8
+ const afterAssertion = vi.fn();
9
+ const el = await $('sel');
10
+ const result = await toHaveChildren.call({}, el, undefined, { wait: 0, beforeAssertion, afterAssertion });
11
+ expect(result.pass).toBe(true);
12
+ expect(beforeAssertion).toBeCalledWith({
13
+ matcherName: 'toHaveChildren',
14
+ options: { wait: 0, beforeAssertion, afterAssertion }
15
+ });
16
+ expect(afterAssertion).toBeCalledWith({
17
+ matcherName: 'toHaveChildren',
18
+ options: { wait: 0, beforeAssertion, afterAssertion },
19
+ result
20
+ });
21
+ });
22
+ test('If no options passed in + children exists', async () => {
23
+ const el = await $('sel');
24
+ const result = await toHaveChildren.call({}, el, {});
25
+ expect(result.pass).toBe(true);
26
+ });
27
+ test('exact number value', async () => {
28
+ const el = await $('sel');
29
+ const result = await toHaveChildren.call({}, el, 2, { wait: 1 });
30
+ expect(result.pass).toBe(true);
31
+ });
32
+ test('exact value', async () => {
33
+ const el = await $('sel');
34
+ const result = await toHaveChildren.call({}, el, { eq: 2, wait: 1 });
35
+ expect(result.pass).toBe(true);
36
+ });
37
+ test('gte value', async () => {
38
+ const el = await $('sel');
39
+ const result = await toHaveChildren.call({}, el, { gte: 2, wait: 1 });
40
+ expect(result.pass).toBe(true);
41
+ });
42
+ test('exact value - failure', async () => {
43
+ const el = await $('sel');
44
+ const result = await toHaveChildren.call({}, el, { eq: 3, wait: 1 });
45
+ expect(result.pass).toBe(false);
46
+ });
47
+ test('lte value - failure', async () => {
48
+ const el = await $('sel');
49
+ const result = await toHaveChildren.call({}, el, { lte: 1, wait: 0 });
50
+ expect(result.pass).toBe(false);
51
+ });
52
+ test('.not exact value - failure', async () => {
53
+ const el = await $('sel');
54
+ const result = await toHaveChildren.bind({ isNot: true })(el, { eq: 2, wait: 0 });
55
+ expect(result.pass).toBe(true);
56
+ });
57
+ test('.not exact value - success', async () => {
58
+ const el = await $('sel');
59
+ const result = await toHaveChildren.bind({ isNot: true })(el, { eq: 3, wait: 1 });
60
+ expect(result.pass).toBe(false);
61
+ });
62
+ });