expect-webdriverio 4.8.1 → 4.9.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.
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,86 @@
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
+ const browserErrorStack = this.errorStack;
64
+ function __INLINE_SNAPSHOT__(inlineSnapshot, message) {
65
+ const error = new Error('inline snapshot');
66
+ if (browserErrorStack && error.stack) {
67
+ error.stack = [
68
+ ...error.stack.split('\n').slice(0, 3),
69
+ ...browserErrorStack
70
+ .split('\n')
71
+ .slice(2)
72
+ .map((line) => line
73
+ .replace(/http:\/\/localhost:\d+/g, '')
74
+ .replace('/@fs/', '/'))
75
+ ].join('\n');
76
+ }
77
+ error.stack = error.stack?.split('\n').filter((line) => (line.includes('__INLINE_SNAPSHOT__') ||
78
+ !(line.includes('__EXTERNAL_MATCHER_TRAP__') ||
79
+ line.includes(`expect-webdriverio${path.sep}lib${path.sep}matchers${path.sep}snapshot.js:`)))).join('\n');
80
+ return toMatchSnapshotHelper(received, message, {
81
+ inlineSnapshot,
82
+ error
83
+ });
84
+ }
85
+ return __INLINE_SNAPSHOT__(inlineSnapshot, message);
86
+ }
package/lib/matchers.js CHANGED
@@ -24,6 +24,7 @@ import * as toHaveStyle from './matchers/element/toHaveStyle.js';
24
24
  import * as toBeRequested from './matchers/mock/toBeRequested.js';
25
25
  import * as toBeRequestedTimes from './matchers/mock/toBeRequestedTimes.js';
26
26
  import * as toBeRequestedWith from './matchers/mock/toBeRequestedWith.js';
27
+ import * as snapshotMatchers from './matchers/snapshot.js';
27
28
  const matchers = {
28
29
  ...toHaveClipboardText,
29
30
  ...toHaveTitle,
@@ -51,6 +52,7 @@ const matchers = {
51
52
  ...toBeRequested,
52
53
  ...toBeRequestedTimes,
53
54
  ...toBeRequestedWith,
55
+ ...snapshotMatchers
54
56
  };
55
57
  Object.keys(matchers).forEach((key) => {
56
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.1",
3
+ "version": "4.9.1",
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,15 +1,16 @@
1
1
  declare namespace ExpectWebdriverIO {
2
- /**
3
- * expect function declaration, containing two generics:
4
- * - T: the type of the actual value, e.g. WebdriverIO.Browser or WebdriverIO.Element
5
- * - R: the type of the return value, e.g. Promise<void> or void
6
- */
7
- function expect<T = unknown, R extends void | Promise<void> = void | Promise<void>>(
8
- actual: T
9
- ): Matchers<R, T>
2
+ const expect: ExpectWebdriverIO.Expect
10
3
  function setOptions(options: DefaultOptions): void
11
4
  function getConfig(): any
12
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
+
13
14
  interface AssertionResult {
14
15
  pass: boolean
15
16
  message(): string
@@ -467,12 +468,10 @@ declare namespace ExpectWebdriverIO {
467
468
  ): R
468
469
 
469
470
  // ==== network mock ====
470
-
471
471
  /**
472
472
  * Check that `WebdriverIO.Mock` was called
473
473
  */
474
474
  toBeRequested(options?: ExpectWebdriverIO.CommandOptions): R
475
-
476
475
  /**
477
476
  * Check that `WebdriverIO.Mock` was called N times
478
477
  */
@@ -480,11 +479,21 @@ declare namespace ExpectWebdriverIO {
480
479
  times: number | ExpectWebdriverIO.NumberOptions,
481
480
  options?: ExpectWebdriverIO.NumberOptions
482
481
  ): R
483
-
484
482
  /**
485
483
  * Check that `WebdriverIO.Mock` was called with the specific parameters
486
484
  */
487
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
488
497
  }
489
498
 
490
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