expect-webdriverio 4.8.0 → 4.9.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.
package/lib/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { expect as expectLib } from 'expect';
2
2
  import wdioMatchers from './matchers.js';
3
- import * as expectUtils from './utils.js';
4
3
  import { DEFAULT_OPTIONS } from './constants.js';
5
4
  expectLib.extend({ ...wdioMatchers });
6
5
  export const expect = expectLib;
@@ -14,4 +13,5 @@ export const setDefaultOptions = (options = {}) => {
14
13
  });
15
14
  };
16
15
  export const setOptions = setDefaultOptions;
17
- export const utils = expectUtils;
16
+ export * from './snapshot.js';
17
+ export * as utils from './utils.js';
@@ -0,0 +1,74 @@
1
+ import path from 'node:path';
2
+ import { expect } from '../index.js';
3
+ import { SnapshotService } from '../snapshot.js';
4
+ function returnSnapshotError(snapshotError) {
5
+ try {
6
+ expect(snapshotError.actual).toBe(snapshotError.expected);
7
+ }
8
+ catch (e) {
9
+ return {
10
+ pass: false,
11
+ message: () => e.message
12
+ };
13
+ }
14
+ throw snapshotError;
15
+ }
16
+ function toMatchSnapshotAssert(received, message, inlineOptions) {
17
+ const snapshotService = SnapshotService.initiate();
18
+ try {
19
+ snapshotService.client.assert({
20
+ received,
21
+ message,
22
+ filepath: snapshotService.currentFilePath,
23
+ name: snapshotService.currentTestName,
24
+ ...(inlineOptions ? {
25
+ ...inlineOptions,
26
+ isInline: true
27
+ } : {
28
+ isInline: false
29
+ })
30
+ });
31
+ return {
32
+ pass: true,
33
+ message: () => 'Snapshot matches'
34
+ };
35
+ }
36
+ catch (e) {
37
+ return returnSnapshotError(e);
38
+ }
39
+ }
40
+ async function toMatchSnapshotAsync(asyncReceived, message, inlineOptions) {
41
+ let received = await asyncReceived;
42
+ if (received && typeof received === 'object' && 'elementId' in received) {
43
+ received = await received.getHTML(true);
44
+ }
45
+ return toMatchSnapshotAssert(received, message, inlineOptions);
46
+ }
47
+ function toMatchSnapshotHelper(received, message, inlineOptions) {
48
+ const snapshotService = SnapshotService.initiate();
49
+ if (!snapshotService.currentFilePath || !snapshotService.currentTestName) {
50
+ throw new Error('Snapshot service is not initialized');
51
+ }
52
+ if (received && typeof received === 'object' &&
53
+ ('elementId' in received ||
54
+ 'then' in received)) {
55
+ return toMatchSnapshotAsync(received, message, inlineOptions);
56
+ }
57
+ return toMatchSnapshotAssert(received, message, inlineOptions);
58
+ }
59
+ export function toMatchSnapshot(received, message) {
60
+ return toMatchSnapshotHelper(received, message);
61
+ }
62
+ export function toMatchInlineSnapshot(received, inlineSnapshot, message) {
63
+ function __INLINE_SNAPSHOT__(inlineSnapshot, message) {
64
+ const error = new Error('inline snapshot');
65
+ error.stack = error.stack?.split('\n').filter((line) => (line.includes('__INLINE_SNAPSHOT__') ||
66
+ !(line.includes('__EXTERNAL_MATCHER_TRAP__') ||
67
+ line.includes(`expect-webdriverio${path.sep}lib${path.sep}matchers${path.sep}snapshot.js:`)))).join('\n');
68
+ return toMatchSnapshotHelper(received, message, {
69
+ inlineSnapshot,
70
+ error
71
+ });
72
+ }
73
+ return __INLINE_SNAPSHOT__(inlineSnapshot, message);
74
+ }
package/lib/matchers.js CHANGED
@@ -14,6 +14,7 @@ import * as toHaveAttribute from './matchers/element/toHaveAttribute.js';
14
14
  import * as toHaveChildren from './matchers/element/toHaveChildren.js';
15
15
  import * as toHaveClass from './matchers/element/toHaveClass.js';
16
16
  import * as toHaveHref from './matchers/element/toHaveHref.js';
17
+ import * as toHaveHTML from './matchers/element/toHaveHTML.js';
17
18
  import * as toHaveId from './matchers/element/toHaveId.js';
18
19
  import * as toHaveSize from './matchers/element/toHaveSize.js';
19
20
  import * as toHaveElementProperty from './matchers/element/toHaveElementProperty.js';
@@ -23,6 +24,7 @@ import * as toHaveStyle from './matchers/element/toHaveStyle.js';
23
24
  import * as toBeRequested from './matchers/mock/toBeRequested.js';
24
25
  import * as toBeRequestedTimes from './matchers/mock/toBeRequestedTimes.js';
25
26
  import * as toBeRequestedWith from './matchers/mock/toBeRequestedWith.js';
27
+ import * as snapshotMatchers from './matchers/snapshot.js';
26
28
  const matchers = {
27
29
  ...toHaveClipboardText,
28
30
  ...toHaveTitle,
@@ -40,6 +42,7 @@ const matchers = {
40
42
  ...toHaveChildren,
41
43
  ...toHaveClass,
42
44
  ...toHaveHref,
45
+ ...toHaveHTML,
43
46
  ...toHaveId,
44
47
  ...toHaveSize,
45
48
  ...toHaveElementProperty,
@@ -49,6 +52,7 @@ const matchers = {
49
52
  ...toBeRequested,
50
53
  ...toBeRequestedTimes,
51
54
  ...toBeRequestedWith,
55
+ ...snapshotMatchers
52
56
  };
53
57
  Object.keys(matchers).forEach((key) => {
54
58
  if (key.endsWith('Fn')) {
@@ -0,0 +1,72 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
7
+ if (kind === "m") throw new TypeError("Private method is not writable");
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
+ };
12
+ var _SnapshotService_instances, _SnapshotService_currentFilePath, _SnapshotService_currentTestName, _SnapshotService_options, _SnapshotService_snapshotResults, _SnapshotService_snapshotEnvironment, _SnapshotService_snapshotClient, _SnapshotService_isEqual;
13
+ import { expect } from '@wdio/globals';
14
+ import { SnapshotClient } from '@vitest/snapshot';
15
+ import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment';
16
+ let service;
17
+ export class SnapshotService {
18
+ constructor(updateState) {
19
+ _SnapshotService_instances.add(this);
20
+ _SnapshotService_currentFilePath.set(this, void 0);
21
+ _SnapshotService_currentTestName.set(this, void 0);
22
+ _SnapshotService_options.set(this, void 0);
23
+ _SnapshotService_snapshotResults.set(this, []);
24
+ _SnapshotService_snapshotEnvironment.set(this, new NodeSnapshotEnvironment());
25
+ _SnapshotService_snapshotClient.set(this, new SnapshotClient({
26
+ isEqual: __classPrivateFieldGet(this, _SnapshotService_instances, "m", _SnapshotService_isEqual).bind(this),
27
+ }));
28
+ __classPrivateFieldSet(this, _SnapshotService_options, {
29
+ updateSnapshot: updateState,
30
+ snapshotEnvironment: __classPrivateFieldGet(this, _SnapshotService_snapshotEnvironment, "f"),
31
+ }, "f");
32
+ }
33
+ get currentFilePath() {
34
+ return __classPrivateFieldGet(this, _SnapshotService_currentFilePath, "f");
35
+ }
36
+ get currentTestName() {
37
+ return __classPrivateFieldGet(this, _SnapshotService_currentTestName, "f");
38
+ }
39
+ get client() {
40
+ return __classPrivateFieldGet(this, _SnapshotService_snapshotClient, "f");
41
+ }
42
+ get results() {
43
+ return __classPrivateFieldGet(this, _SnapshotService_snapshotResults, "f");
44
+ }
45
+ beforeTest(test) {
46
+ __classPrivateFieldSet(this, _SnapshotService_currentFilePath, test.file, "f");
47
+ __classPrivateFieldSet(this, _SnapshotService_currentTestName, `${test.parent} > ${test.title}`, "f");
48
+ __classPrivateFieldGet(this, _SnapshotService_snapshotClient, "f").startCurrentRun(test.file, test.fullTitle, __classPrivateFieldGet(this, _SnapshotService_options, "f"));
49
+ }
50
+ async afterTest() {
51
+ const result = await __classPrivateFieldGet(this, _SnapshotService_snapshotClient, "f").finishCurrentRun();
52
+ if (!result) {
53
+ return;
54
+ }
55
+ __classPrivateFieldGet(this, _SnapshotService_snapshotResults, "f").push(result);
56
+ }
57
+ static initiate(updateState = 'new') {
58
+ if (!service) {
59
+ service = new SnapshotService(updateState);
60
+ }
61
+ return service;
62
+ }
63
+ }
64
+ _SnapshotService_currentFilePath = new WeakMap(), _SnapshotService_currentTestName = new WeakMap(), _SnapshotService_options = new WeakMap(), _SnapshotService_snapshotResults = new WeakMap(), _SnapshotService_snapshotEnvironment = new WeakMap(), _SnapshotService_snapshotClient = new WeakMap(), _SnapshotService_instances = new WeakSet(), _SnapshotService_isEqual = function _SnapshotService_isEqual(received, expected) {
65
+ try {
66
+ expect(received).toBe(expected);
67
+ return true;
68
+ }
69
+ catch {
70
+ return false;
71
+ }
72
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expect-webdriverio",
3
- "version": "4.8.0",
3
+ "version": "4.9.0",
4
4
  "author": "Mykola Grybyk <mykola.grybyk@gmail.com>",
5
5
  "description": "WebdriverIO Assertion Library",
6
6
  "license": "MIT",
@@ -75,8 +75,8 @@
75
75
  "rimraf": "^5.0.5",
76
76
  "shelljs": "^0.8.5",
77
77
  "typescript": "^5.3.3",
78
- "vitest": "1.1.3",
79
- "webdriverio": "8.27.0"
78
+ "vitest": "1.2.0",
79
+ "webdriverio": "8.27.2"
80
80
  },
81
81
  "optionalDependencies": {
82
82
  "@wdio/globals": "^8.27.0",
@@ -84,6 +84,7 @@
84
84
  "webdriverio": "^8.27.0"
85
85
  },
86
86
  "dependencies": {
87
+ "@vitest/snapshot": "^1.2.1",
87
88
  "expect": "^29.7.0",
88
89
  "jest-matcher-utils": "^29.7.0",
89
90
  "lodash.isequal": "^4.5.0"
@@ -1,10 +1,16 @@
1
1
  declare namespace ExpectWebdriverIO {
2
- function expect<T = unknown, R extends void | Promise<void> = void | Promise<void>>(
3
- actual: T
4
- ): Matchers<R, T>
2
+ const expect: ExpectWebdriverIO.Expect
5
3
  function setOptions(options: DefaultOptions): void
6
4
  function getConfig(): any
7
5
 
6
+ class SnapshotService {
7
+ static initiate(
8
+ updateState?: import('@vitest/snapshot').SnapshotUpdateState
9
+ ): import('@wdio/types').Services.ServiceInstance & {
10
+ results: import('@vitest/snapshot').SnapshotResult[]
11
+ }
12
+ }
13
+
8
14
  interface AssertionResult {
9
15
  pass: boolean
10
16
  message(): string
@@ -462,12 +468,10 @@ declare namespace ExpectWebdriverIO {
462
468
  ): R
463
469
 
464
470
  // ==== network mock ====
465
-
466
471
  /**
467
472
  * Check that `WebdriverIO.Mock` was called
468
473
  */
469
474
  toBeRequested(options?: ExpectWebdriverIO.CommandOptions): R
470
-
471
475
  /**
472
476
  * Check that `WebdriverIO.Mock` was called N times
473
477
  */
@@ -475,11 +479,21 @@ declare namespace ExpectWebdriverIO {
475
479
  times: number | ExpectWebdriverIO.NumberOptions,
476
480
  options?: ExpectWebdriverIO.NumberOptions
477
481
  ): R
478
-
479
482
  /**
480
483
  * Check that `WebdriverIO.Mock` was called with the specific parameters
481
484
  */
482
485
  toBeRequestedWith(requestedWith: RequestedWith, options?: ExpectWebdriverIO.CommandOptions): R
486
+ /**
487
+ * snapshot matcher
488
+ * @param label optional snapshot label
489
+ */
490
+ toMatchSnapshot(label?: string): R
491
+ /**
492
+ * inline snapshot matcher
493
+ * @param snapshot snapshot string (autogenerated if not specified)
494
+ * @param label optional snapshot label
495
+ */
496
+ toMatchInlineSnapshot(snapshot?: string, label?: string): R
483
497
  }
484
498
 
485
499
  type RequestedWith = {
@@ -10,6 +10,11 @@ declare namespace ExpectWebdriverIO {
10
10
  rejects: Matchers<R, T>
11
11
  }
12
12
 
13
+ /**
14
+ * expect function declaration, containing two generics:
15
+ * - T: the type of the actual value, e.g. WebdriverIO.Browser or WebdriverIO.Element
16
+ * - R: the type of the return value, e.g. Promise<void> or void
17
+ */
13
18
  type Expect = {
14
19
  <T = unknown, R extends void | Promise<void> = void | Promise<void>>(actual: T): Matchers<R, T>
15
20
  extend(map: Record<string, Function>): void