@mobilewright/core 0.0.41 → 0.0.43
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/dist/device.d.ts +7 -1
- package/dist/device.d.ts.map +1 -1
- package/dist/device.js +17 -2
- package/dist/device.js.map +1 -1
- package/dist/device.test.d.ts +2 -0
- package/dist/device.test.d.ts.map +1 -0
- package/dist/device.test.js +39 -0
- package/dist/device.test.js.map +1 -0
- package/dist/expect.d.ts +82 -11
- package/dist/expect.d.ts.map +1 -1
- package/dist/expect.js +181 -22
- package/dist/expect.js.map +1 -1
- package/dist/expect.test.js +17 -0
- package/dist/expect.test.js.map +1 -1
- package/dist/fake-webview-session.d.ts +14 -0
- package/dist/fake-webview-session.d.ts.map +1 -0
- package/dist/fake-webview-session.js +26 -0
- package/dist/fake-webview-session.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/locator.d.ts +26 -5
- package/dist/locator.d.ts.map +1 -1
- package/dist/locator.js +31 -10
- package/dist/locator.js.map +1 -1
- package/dist/locator.test.js +213 -0
- package/dist/locator.test.js.map +1 -1
- package/dist/page.d.ts +52 -0
- package/dist/page.d.ts.map +1 -0
- package/dist/page.js +226 -0
- package/dist/page.js.map +1 -0
- package/dist/page.test.d.ts +2 -0
- package/dist/page.test.d.ts.map +1 -0
- package/dist/page.test.js +263 -0
- package/dist/page.test.js.map +1 -0
- package/dist/playwright-engine.d.ts +23 -0
- package/dist/playwright-engine.d.ts.map +1 -0
- package/dist/playwright-engine.js +79 -0
- package/dist/playwright-engine.js.map +1 -0
- package/dist/playwright-engine.test.d.ts +2 -0
- package/dist/playwright-engine.test.d.ts.map +1 -0
- package/dist/playwright-engine.test.js +45 -0
- package/dist/playwright-engine.test.js.map +1 -0
- package/dist/query-engine.d.ts +19 -0
- package/dist/query-engine.d.ts.map +1 -1
- package/dist/query-engine.js +80 -0
- package/dist/query-engine.js.map +1 -1
- package/dist/query-engine.test.js +187 -1
- package/dist/query-engine.test.js.map +1 -1
- package/dist/screen.d.ts +11 -1
- package/dist/screen.d.ts.map +1 -1
- package/dist/screen.js +16 -0
- package/dist/screen.js.map +1 -1
- package/dist/screen.test.d.ts +2 -0
- package/dist/screen.test.d.ts.map +1 -0
- package/dist/screen.test.js +69 -0
- package/dist/screen.test.js.map +1 -0
- package/dist/stackTrace.d.ts +3 -0
- package/dist/stackTrace.d.ts.map +1 -1
- package/dist/stackTrace.js +10 -0
- package/dist/stackTrace.js.map +1 -1
- package/dist/stackTrace.test.d.ts +2 -0
- package/dist/stackTrace.test.d.ts.map +1 -0
- package/dist/stackTrace.test.js +43 -0
- package/dist/stackTrace.test.js.map +1 -0
- package/dist/web-expect-matcher.d.ts +29 -0
- package/dist/web-expect-matcher.d.ts.map +1 -0
- package/dist/web-expect-matcher.js +23 -0
- package/dist/web-expect-matcher.js.map +1 -0
- package/dist/web-expect-matcher.test.d.ts +2 -0
- package/dist/web-expect-matcher.test.d.ts.map +1 -0
- package/dist/web-expect-matcher.test.js +21 -0
- package/dist/web-expect-matcher.test.js.map +1 -0
- package/dist/web-expect.test.d.ts +2 -0
- package/dist/web-expect.test.d.ts.map +1 -0
- package/dist/web-expect.test.js +93 -0
- package/dist/web-expect.test.js.map +1 -0
- package/dist/web-locator-pwexpect.test.d.ts +2 -0
- package/dist/web-locator-pwexpect.test.d.ts.map +1 -0
- package/dist/web-locator-pwexpect.test.js +36 -0
- package/dist/web-locator-pwexpect.test.js.map +1 -0
- package/dist/web-locator-reinjection.test.d.ts +2 -0
- package/dist/web-locator-reinjection.test.d.ts.map +1 -0
- package/dist/web-locator-reinjection.test.js +83 -0
- package/dist/web-locator-reinjection.test.js.map +1 -0
- package/dist/web-locator.d.ts +120 -0
- package/dist/web-locator.d.ts.map +1 -0
- package/dist/web-locator.js +332 -0
- package/dist/web-locator.js.map +1 -0
- package/dist/web-locator.test.d.ts +2 -0
- package/dist/web-locator.test.d.ts.map +1 -0
- package/dist/web-locator.test.js +424 -0
- package/dist/web-locator.test.js.map +1 -0
- package/dist/webview-locator.d.ts +14 -0
- package/dist/webview-locator.d.ts.map +1 -0
- package/dist/webview-locator.js +95 -0
- package/dist/webview-locator.js.map +1 -0
- package/dist/webview-locator.test.d.ts +2 -0
- package/dist/webview-locator.test.d.ts.map +1 -0
- package/dist/webview-locator.test.js +203 -0
- package/dist/webview-locator.test.js.map +1 -0
- package/package.json +3 -2
package/dist/device.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import type { AppInfo, ConnectionConfig, LaunchOptions, MobilewrightDriver, Orientation, RecordingOptions, RecordingResult, Session } from '@mobilewright/protocol';
|
|
1
|
+
import type { AppInfo, ConnectionConfig, LaunchOptions, MobilewrightDriver, Orientation, RecordingOptions, RecordingResult, ScreenSize, Session } from '@mobilewright/protocol';
|
|
2
2
|
import { Screen } from './screen.js';
|
|
3
3
|
import type { LocatorOptions } from './locator.js';
|
|
4
4
|
export interface DeviceOptions {
|
|
5
5
|
locatorDefaults?: LocatorOptions;
|
|
6
|
+
/** Timeout waiting for app to reach foreground after launch, in ms. Default: 20000. */
|
|
7
|
+
appLaunchTimeout?: number;
|
|
8
|
+
/** Timeout for app installation in ms. Default: none (no limit). */
|
|
9
|
+
installTimeout?: number;
|
|
6
10
|
}
|
|
7
11
|
export declare class Device {
|
|
8
12
|
readonly driver: MobilewrightDriver;
|
|
@@ -19,6 +23,8 @@ export declare class Device {
|
|
|
19
23
|
get screen(): Screen;
|
|
20
24
|
getOrientation(): Promise<Orientation>;
|
|
21
25
|
setOrientation(orientation: Orientation): Promise<void>;
|
|
26
|
+
/** Screen dimensions and pixel density: { width, height, scale }. */
|
|
27
|
+
screenSize(): Promise<ScreenSize>;
|
|
22
28
|
openUrl(url: string): Promise<void>;
|
|
23
29
|
/** Alias for openUrl — matches Playwright's page.goto(). */
|
|
24
30
|
goto(url: string): Promise<void>;
|
package/dist/device.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../src/device.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,OAAO,EACP,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,OAAO,EACR,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAOnD,MAAM,WAAW,aAAa;IAC5B,eAAe,CAAC,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../src/device.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,OAAO,EACP,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,OAAO,EACR,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAOnD,MAAM,WAAW,aAAa;IAC5B,eAAe,CAAC,EAAE,cAAc,CAAC;IACjC,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAYD,qBAAa,MAAM;IACjB,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;gBAEzB,MAAM,EAAE,kBAAkB,EAAE,IAAI,GAAE,aAAkB;IAKhE,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAMtC,OAAO,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAInD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,uEAAuE;IACjE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B,IAAI,MAAM,IAAI,MAAM,CAGnB;IAIK,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAItC,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7D,qEAAqE;IAC/D,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC;IAIjC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,4DAA4D;IACtD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhC,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BhE,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7C,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAI9B,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;IAIpC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7C,cAAc,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,aAAa,IAAI,OAAO,CAAC,eAAe,CAAC;CAGhD"}
|
package/dist/device.js
CHANGED
|
@@ -3,6 +3,12 @@ import { Screen } from './screen.js';
|
|
|
3
3
|
import { retryUntil } from './poll.js';
|
|
4
4
|
const debug = createDebug('mw:device');
|
|
5
5
|
const LAUNCH_APP_TIMEOUT = 20_000;
|
|
6
|
+
function raceWithTimeout(promise, ms, message) {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
const timer = setTimeout(() => reject(new Error(message)), ms);
|
|
9
|
+
promise.then((value) => { clearTimeout(timer); resolve(value); }, (err) => { clearTimeout(timer); reject(err); });
|
|
10
|
+
});
|
|
11
|
+
}
|
|
6
12
|
export class Device {
|
|
7
13
|
constructor(driver, opts = {}) {
|
|
8
14
|
this.cleanupCallbacks = [];
|
|
@@ -40,6 +46,10 @@ export class Device {
|
|
|
40
46
|
async setOrientation(orientation) {
|
|
41
47
|
return this.driver.setOrientation(orientation);
|
|
42
48
|
}
|
|
49
|
+
/** Screen dimensions and pixel density: { width, height, scale }. */
|
|
50
|
+
async screenSize() {
|
|
51
|
+
return this.driver.getScreenSize();
|
|
52
|
+
}
|
|
43
53
|
async openUrl(url) {
|
|
44
54
|
return this.driver.openUrl(url);
|
|
45
55
|
}
|
|
@@ -53,9 +63,10 @@ export class Device {
|
|
|
53
63
|
if (opts?.noWaitAfter) {
|
|
54
64
|
return;
|
|
55
65
|
}
|
|
66
|
+
const timeout = this.opts.appLaunchTimeout ?? LAUNCH_APP_TIMEOUT;
|
|
56
67
|
debug('waiting for %s to reach foreground', bundleId);
|
|
57
68
|
try {
|
|
58
|
-
await retryUntil(() => this.getForegroundApp(), (app) => app.bundleId === bundleId,
|
|
69
|
+
await retryUntil(() => this.getForegroundApp(), (app) => app.bundleId === bundleId, timeout, `launchApp: timed out waiting for "${bundleId}" to be in foreground`);
|
|
59
70
|
debug('%s is in foreground', bundleId);
|
|
60
71
|
}
|
|
61
72
|
catch (err) {
|
|
@@ -80,7 +91,11 @@ export class Device {
|
|
|
80
91
|
return this.driver.getForegroundApp();
|
|
81
92
|
}
|
|
82
93
|
async installApp(path) {
|
|
83
|
-
|
|
94
|
+
const { installTimeout } = this.opts;
|
|
95
|
+
if (installTimeout === undefined) {
|
|
96
|
+
return this.driver.installApp(path);
|
|
97
|
+
}
|
|
98
|
+
return raceWithTimeout(this.driver.installApp(path), installTimeout, `installApp timed out after ${installTimeout}ms`);
|
|
84
99
|
}
|
|
85
100
|
async uninstallApp(bundleId) {
|
|
86
101
|
return this.driver.uninstallApp(bundleId);
|
package/dist/device.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device.js","sourceRoot":"","sources":["../src/device.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"device.js","sourceRoot":"","sources":["../src/device.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.test.d.ts","sourceRoot":"","sources":["../src/device.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
import { Device } from './device.js';
|
|
3
|
+
function createMockDriver(screenSize) {
|
|
4
|
+
return {
|
|
5
|
+
connect: async () => ({ deviceId: 'device1', platform: 'ios' }),
|
|
6
|
+
disconnect: async () => { },
|
|
7
|
+
getViewHierarchy: async () => [],
|
|
8
|
+
tap: async () => { },
|
|
9
|
+
doubleTap: async () => { },
|
|
10
|
+
longPress: async () => { },
|
|
11
|
+
typeText: async () => { },
|
|
12
|
+
swipe: async () => { },
|
|
13
|
+
gesture: async () => { },
|
|
14
|
+
pressButton: async () => { },
|
|
15
|
+
screenshot: async () => Buffer.from(''),
|
|
16
|
+
getScreenSize: async () => screenSize,
|
|
17
|
+
getOrientation: async () => 'portrait',
|
|
18
|
+
setOrientation: async () => { },
|
|
19
|
+
launchApp: async () => { },
|
|
20
|
+
terminateApp: async () => { },
|
|
21
|
+
listApps: async () => [],
|
|
22
|
+
getForegroundApp: async () => ({ bundleId: 'com.test' }),
|
|
23
|
+
installApp: async () => { },
|
|
24
|
+
uninstallApp: async () => { },
|
|
25
|
+
listDevices: async () => [],
|
|
26
|
+
openUrl: async () => { },
|
|
27
|
+
startRecording: async () => { },
|
|
28
|
+
stopRecording: async () => ({}),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
test.describe('Device.screenSize', () => {
|
|
32
|
+
test('returns the width, height, and scale from the driver', async () => {
|
|
33
|
+
const driver = createMockDriver({ width: 390, height: 844, scale: 3 });
|
|
34
|
+
const device = new Device(driver);
|
|
35
|
+
const size = await device.screenSize();
|
|
36
|
+
expect(size).toEqual({ width: 390, height: 844, scale: 3 });
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=device.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.test.js","sourceRoot":"","sources":["../src/device.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAQhD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,SAAS,gBAAgB,CAAC,UAAsB;IAC9C,OAAO;QACL,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAc,EAAE,CAAC;QACxE,UAAU,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC1B,gBAAgB,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;QAChC,GAAG,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACnB,SAAS,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACzB,SAAS,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACzB,QAAQ,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACxB,KAAK,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACrB,OAAO,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACvB,WAAW,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC3B,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,aAAa,EAAE,KAAK,IAAI,EAAE,CAAC,UAAU;QACrC,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC,UAAyB;QACrD,cAAc,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC9B,SAAS,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACzB,YAAY,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC5B,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,EAAe;QACrC,gBAAgB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;QACxD,UAAU,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC1B,YAAY,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC5B,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,EAAkB;QAC3C,OAAO,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACvB,cAAc,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC9B,aAAa,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;KAChC,CAAC;AACJ,CAAC;AAED,IAAI,CAAC,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACtC,IAAI,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACvE,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;QAElC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAEvC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/expect.d.ts
CHANGED
|
@@ -1,24 +1,55 @@
|
|
|
1
|
-
import type { Locator } from './locator.js';
|
|
1
|
+
import type { Locator, StepFn } from './locator.js';
|
|
2
|
+
import { Page } from './page.js';
|
|
3
|
+
import { WebLocator } from './web-locator.js';
|
|
2
4
|
export interface ExpectOptions {
|
|
3
5
|
timeout?: number;
|
|
4
6
|
}
|
|
5
7
|
/**
|
|
6
|
-
* Playwright-style expect for mobile locators and plain values.
|
|
8
|
+
* Playwright-style expect for mobile locators, web locators, pages, and plain values.
|
|
7
9
|
*
|
|
8
10
|
* Usage:
|
|
9
11
|
* expect(locator).toBeVisible()
|
|
10
|
-
* expect(
|
|
11
|
-
* expect(
|
|
12
|
+
* expect(page).toHaveURL(/dashboard/)
|
|
13
|
+
* expect(webLocator).toHaveText('Hello')
|
|
12
14
|
* expect(42).toBe(42)
|
|
13
15
|
*/
|
|
16
|
+
export declare function expect(actual: Page): PageAssertions;
|
|
17
|
+
export declare function expect(actual: WebLocator): WebLocatorAssertions;
|
|
14
18
|
export declare function expect(actual: Locator): LocatorAssertions;
|
|
15
19
|
export declare function expect<T>(actual: T): ValueAssertions<T>;
|
|
20
|
+
interface LocatorLike {
|
|
21
|
+
isVisible(opts?: {
|
|
22
|
+
timeout?: number;
|
|
23
|
+
}): Promise<boolean>;
|
|
24
|
+
isEnabled(opts?: {
|
|
25
|
+
timeout?: number;
|
|
26
|
+
}): Promise<boolean>;
|
|
27
|
+
isChecked(opts?: {
|
|
28
|
+
timeout?: number;
|
|
29
|
+
}): Promise<boolean>;
|
|
30
|
+
isSelected?(opts?: {
|
|
31
|
+
timeout?: number;
|
|
32
|
+
}): Promise<boolean>;
|
|
33
|
+
isFocused?(opts?: {
|
|
34
|
+
timeout?: number;
|
|
35
|
+
}): Promise<boolean>;
|
|
36
|
+
getText(opts?: {
|
|
37
|
+
timeout?: number;
|
|
38
|
+
}): Promise<string>;
|
|
39
|
+
getValue(opts?: {
|
|
40
|
+
timeout?: number;
|
|
41
|
+
}): Promise<string>;
|
|
42
|
+
count(): Promise<number>;
|
|
43
|
+
expectTimeout?: number;
|
|
44
|
+
_stepFn?: StepFn | null;
|
|
45
|
+
}
|
|
16
46
|
declare class LocatorAssertions {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
constructor(locator:
|
|
47
|
+
protected readonly locator: LocatorLike;
|
|
48
|
+
protected readonly negated: boolean;
|
|
49
|
+
constructor(locator: LocatorLike, negated: boolean);
|
|
20
50
|
get not(): LocatorAssertions;
|
|
21
|
-
private
|
|
51
|
+
private assertionTimeout;
|
|
52
|
+
protected _wrapAssertion<T>(method: string, fn: () => Promise<T>): Promise<T>;
|
|
22
53
|
toBeVisible(opts?: ExpectOptions): Promise<void>;
|
|
23
54
|
toBeHidden(opts?: ExpectOptions): Promise<void>;
|
|
24
55
|
toBeEnabled(opts?: ExpectOptions): Promise<void>;
|
|
@@ -31,9 +62,9 @@ declare class LocatorAssertions {
|
|
|
31
62
|
toHaveCount(expected: number, opts?: ExpectOptions): Promise<void>;
|
|
32
63
|
toBeEmpty(opts?: ExpectOptions): Promise<void>;
|
|
33
64
|
toHaveValue(expected: string | RegExp, opts?: ExpectOptions): Promise<void>;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
65
|
+
protected assertBoolean(name: string, poll: () => Promise<boolean>, opts?: ExpectOptions): Promise<void>;
|
|
66
|
+
protected assertText(predicate: (text: string) => boolean, expected: string | RegExp, opts?: ExpectOptions): Promise<void>;
|
|
67
|
+
protected retryAssertion<T>(poll: () => Promise<T>, predicate: (value: T) => boolean, timeout: number, failMessage: string | (() => string)): Promise<void>;
|
|
37
68
|
}
|
|
38
69
|
declare class ValueAssertions<T> {
|
|
39
70
|
private readonly actual;
|
|
@@ -64,6 +95,46 @@ declare class ValueAssertions<T> {
|
|
|
64
95
|
toThrow(expected?: string | RegExp): void;
|
|
65
96
|
private assert;
|
|
66
97
|
}
|
|
98
|
+
declare class PageAssertions {
|
|
99
|
+
private readonly page;
|
|
100
|
+
private readonly negated;
|
|
101
|
+
constructor(page: Page, negated: boolean);
|
|
102
|
+
get not(): PageAssertions;
|
|
103
|
+
private _wrapAssertion;
|
|
104
|
+
private matches;
|
|
105
|
+
toHaveURL(url: string | RegExp, opts?: ExpectOptions): Promise<void>;
|
|
106
|
+
toHaveTitle(title: string | RegExp, opts?: ExpectOptions): Promise<void>;
|
|
107
|
+
}
|
|
108
|
+
declare class WebLocatorAssertions {
|
|
109
|
+
private readonly webLocator;
|
|
110
|
+
private readonly negated;
|
|
111
|
+
constructor(webLocator: WebLocator, negated: boolean);
|
|
112
|
+
get not(): WebLocatorAssertions;
|
|
113
|
+
private assertionTimeout;
|
|
114
|
+
private runMatcher;
|
|
115
|
+
toBeVisible(opts?: ExpectOptions): Promise<void>;
|
|
116
|
+
toBeHidden(opts?: ExpectOptions): Promise<void>;
|
|
117
|
+
toBeEnabled(opts?: ExpectOptions): Promise<void>;
|
|
118
|
+
toBeDisabled(opts?: ExpectOptions): Promise<void>;
|
|
119
|
+
toBeEditable(opts?: ExpectOptions): Promise<void>;
|
|
120
|
+
toBeFocused(opts?: ExpectOptions): Promise<void>;
|
|
121
|
+
toBeAttached(opts?: ExpectOptions): Promise<void>;
|
|
122
|
+
toBeInViewport(opts?: ExpectOptions & {
|
|
123
|
+
ratio?: number;
|
|
124
|
+
}): Promise<void>;
|
|
125
|
+
toBeChecked(opts?: ExpectOptions): Promise<void>;
|
|
126
|
+
toBeEmpty(opts?: ExpectOptions): Promise<void>;
|
|
127
|
+
toHaveText(expected: string | RegExp, opts?: ExpectOptions): Promise<void>;
|
|
128
|
+
toContainText(expected: string | RegExp, opts?: ExpectOptions): Promise<void>;
|
|
129
|
+
toHaveValue(expected: string | RegExp, opts?: ExpectOptions): Promise<void>;
|
|
130
|
+
toHaveCount(expected: number, opts?: ExpectOptions): Promise<void>;
|
|
131
|
+
toHaveAttribute(name: string, expected: string | RegExp, opts?: ExpectOptions): Promise<void>;
|
|
132
|
+
toHaveClass(expected: string | RegExp, opts?: ExpectOptions): Promise<void>;
|
|
133
|
+
toContainClass(expected: string | RegExp, opts?: ExpectOptions): Promise<void>;
|
|
134
|
+
toHaveCSS(name: string, expected: string | RegExp, opts?: ExpectOptions): Promise<void>;
|
|
135
|
+
toHaveId(expected: string | RegExp, opts?: ExpectOptions): Promise<void>;
|
|
136
|
+
toHaveJSProperty(name: string, expected: unknown, opts?: ExpectOptions): Promise<void>;
|
|
137
|
+
}
|
|
67
138
|
export declare class ExpectError extends Error {
|
|
68
139
|
constructor(message: string);
|
|
69
140
|
}
|
package/dist/expect.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../src/expect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../src/expect.ts"],"names":[],"mappings":"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"}
|
package/dist/expect.js
CHANGED
|
@@ -1,13 +1,38 @@
|
|
|
1
1
|
import { LocatorError } from './locator.js';
|
|
2
|
+
import { Page } from './page.js';
|
|
3
|
+
import { WebLocator } from './web-locator.js';
|
|
2
4
|
import { retryUntil } from './poll.js';
|
|
3
|
-
import { filterStack,
|
|
5
|
+
import { filterStack, runStep } from './stackTrace.js';
|
|
6
|
+
import { textValue } from './web-expect-matcher.js';
|
|
4
7
|
const DEFAULT_TIMEOUT = 5_000;
|
|
5
8
|
export function expect(actual) {
|
|
9
|
+
if (actual instanceof Page) {
|
|
10
|
+
return new PageAssertions(actual, false);
|
|
11
|
+
}
|
|
12
|
+
if (actual instanceof WebLocator) {
|
|
13
|
+
return new WebLocatorAssertions(actual, false);
|
|
14
|
+
}
|
|
6
15
|
if (actual && typeof actual === 'object' && 'tap' in actual && 'getText' in actual) {
|
|
7
16
|
return new LocatorAssertions(actual, false);
|
|
8
17
|
}
|
|
9
18
|
return new ValueAssertions(actual, false);
|
|
10
19
|
}
|
|
20
|
+
// Wrap an assertion body as a reporter step titled after the matcher, shared by
|
|
21
|
+
// all assertion classes so the title/negation convention lives in one place.
|
|
22
|
+
function wrapAssertion(stepFn, negated, method, fn) {
|
|
23
|
+
const title = negated ? `expect.not.${method}()` : `expect.${method}()`;
|
|
24
|
+
return runStep(stepFn, title, fn);
|
|
25
|
+
}
|
|
26
|
+
// Poll until `predicate` holds (or the timeout elapses), re-raising any failure
|
|
27
|
+
// as an ExpectError. The predicate must already account for negation.
|
|
28
|
+
async function retryAssertion(poll, predicate, timeout, failMessage) {
|
|
29
|
+
try {
|
|
30
|
+
await retryUntil(poll, predicate, timeout, failMessage);
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
throw new ExpectError(e instanceof Error ? e.message : String(e));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
11
36
|
class LocatorAssertions {
|
|
12
37
|
constructor(locator, negated) {
|
|
13
38
|
this.locator = locator;
|
|
@@ -16,14 +41,11 @@ class LocatorAssertions {
|
|
|
16
41
|
get not() {
|
|
17
42
|
return new LocatorAssertions(this.locator, !this.negated);
|
|
18
43
|
}
|
|
44
|
+
assertionTimeout(opts) {
|
|
45
|
+
return opts?.timeout ?? this.locator.expectTimeout ?? DEFAULT_TIMEOUT;
|
|
46
|
+
}
|
|
19
47
|
_wrapAssertion(method, fn) {
|
|
20
|
-
|
|
21
|
-
const title = this.negated ? `expect.not.${method}()` : `expect.${method}()`;
|
|
22
|
-
if (stepFn) {
|
|
23
|
-
const location = captureLocation();
|
|
24
|
-
return stepFn(title, fn, location);
|
|
25
|
-
}
|
|
26
|
-
return fn();
|
|
48
|
+
return wrapAssertion(this.locator._stepFn, this.negated, method, fn);
|
|
27
49
|
}
|
|
28
50
|
async toBeVisible(opts) {
|
|
29
51
|
return this._wrapAssertion('toBeVisible', async () => {
|
|
@@ -53,12 +75,20 @@ class LocatorAssertions {
|
|
|
53
75
|
}
|
|
54
76
|
async toBeSelected(opts) {
|
|
55
77
|
return this._wrapAssertion('toBeSelected', async () => {
|
|
56
|
-
|
|
78
|
+
const isSelected = this.locator.isSelected?.bind(this.locator);
|
|
79
|
+
if (!isSelected) {
|
|
80
|
+
throw new ExpectError('toBeSelected() is not supported for this locator');
|
|
81
|
+
}
|
|
82
|
+
await this.assertBoolean('selected', () => isSelected({ timeout: 0 }), opts);
|
|
57
83
|
});
|
|
58
84
|
}
|
|
59
85
|
async toBeFocused(opts) {
|
|
60
86
|
return this._wrapAssertion('toBeFocused', async () => {
|
|
61
|
-
|
|
87
|
+
const isFocused = this.locator.isFocused?.bind(this.locator);
|
|
88
|
+
if (!isFocused) {
|
|
89
|
+
throw new ExpectError('toBeFocused() is not supported for this locator');
|
|
90
|
+
}
|
|
91
|
+
await this.assertBoolean('focused', () => isFocused({ timeout: 0 }), opts);
|
|
62
92
|
});
|
|
63
93
|
}
|
|
64
94
|
async toBeChecked(opts) {
|
|
@@ -82,7 +112,7 @@ class LocatorAssertions {
|
|
|
82
112
|
await this.retryAssertion(async () => { lastCount = await this.locator.count(); return lastCount; }, (count) => {
|
|
83
113
|
const matches = count === expected;
|
|
84
114
|
return this.negated ? !matches : matches;
|
|
85
|
-
}, opts
|
|
115
|
+
}, this.assertionTimeout(opts), () => this.negated
|
|
86
116
|
? `Expected element count NOT to be ${expected}, but got ${lastCount}`
|
|
87
117
|
: `Expected element count to be ${expected}, but got ${lastCount}`);
|
|
88
118
|
});
|
|
@@ -107,7 +137,7 @@ class LocatorAssertions {
|
|
|
107
137
|
}
|
|
108
138
|
const isEmpty = value === '';
|
|
109
139
|
return this.negated ? !isEmpty : isEmpty;
|
|
110
|
-
}, opts
|
|
140
|
+
}, this.assertionTimeout(opts), () => this.negated
|
|
111
141
|
? 'Expected element NOT to be empty, but it was'
|
|
112
142
|
: `Expected element to be empty, but got "${lastValue}"`);
|
|
113
143
|
});
|
|
@@ -132,13 +162,13 @@ class LocatorAssertions {
|
|
|
132
162
|
}
|
|
133
163
|
const matches = expected instanceof RegExp ? expected.test(value) : value === expected;
|
|
134
164
|
return this.negated ? !matches : matches;
|
|
135
|
-
}, opts
|
|
165
|
+
}, this.assertionTimeout(opts), () => this.negated
|
|
136
166
|
? `Expected element NOT to have value "${expected}", but got "${lastValue}"`
|
|
137
167
|
: `Expected element to have value "${expected}", but got "${lastValue}"`);
|
|
138
168
|
});
|
|
139
169
|
}
|
|
140
170
|
async assertBoolean(name, poll, opts) {
|
|
141
|
-
await this.retryAssertion(poll, (result) => (this.negated ? !result : result), opts
|
|
171
|
+
await this.retryAssertion(poll, (result) => (this.negated ? !result : result), this.assertionTimeout(opts), this.negated
|
|
142
172
|
? `Expected element to NOT be ${name}, but it was`
|
|
143
173
|
: `Expected element to be ${name}, but it was not`);
|
|
144
174
|
}
|
|
@@ -161,17 +191,12 @@ class LocatorAssertions {
|
|
|
161
191
|
}
|
|
162
192
|
const matches = predicate(text);
|
|
163
193
|
return this.negated ? !matches : matches;
|
|
164
|
-
}, opts
|
|
194
|
+
}, this.assertionTimeout(opts), () => this.negated
|
|
165
195
|
? `Expected element NOT to have text "${expected}", but got "${lastText}"`
|
|
166
196
|
: `Expected element to have text "${expected}", but got "${lastText}"`);
|
|
167
197
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
await retryUntil(poll, predicate, timeout, failMessage);
|
|
171
|
-
}
|
|
172
|
-
catch (e) {
|
|
173
|
-
throw new ExpectError(e instanceof Error ? e.message : String(e));
|
|
174
|
-
}
|
|
198
|
+
retryAssertion(poll, predicate, timeout, failMessage) {
|
|
199
|
+
return retryAssertion(poll, predicate, timeout, failMessage);
|
|
175
200
|
}
|
|
176
201
|
}
|
|
177
202
|
class ValueAssertions {
|
|
@@ -297,6 +322,140 @@ class ValueAssertions {
|
|
|
297
322
|
}
|
|
298
323
|
}
|
|
299
324
|
}
|
|
325
|
+
// ─── PageAssertions ───────────────────────────────────────────
|
|
326
|
+
class PageAssertions {
|
|
327
|
+
constructor(page, negated) {
|
|
328
|
+
this.page = page;
|
|
329
|
+
this.negated = negated;
|
|
330
|
+
}
|
|
331
|
+
get not() {
|
|
332
|
+
return new PageAssertions(this.page, !this.negated);
|
|
333
|
+
}
|
|
334
|
+
_wrapAssertion(method, fn) {
|
|
335
|
+
return wrapAssertion(this.page._stepFn, this.negated, method, fn);
|
|
336
|
+
}
|
|
337
|
+
// Applies negation so callers pass the plain "does it match?" predicate.
|
|
338
|
+
matches(pass) {
|
|
339
|
+
return this.negated ? !pass : pass;
|
|
340
|
+
}
|
|
341
|
+
async toHaveURL(url, opts) {
|
|
342
|
+
return this._wrapAssertion('toHaveURL', async () => {
|
|
343
|
+
let last = '';
|
|
344
|
+
await retryAssertion(async () => { try {
|
|
345
|
+
last = await this.page.url();
|
|
346
|
+
}
|
|
347
|
+
catch {
|
|
348
|
+
last = '';
|
|
349
|
+
} return last; }, (current) => this.matches(url instanceof RegExp ? url.test(current) : current === url), opts?.timeout ?? DEFAULT_TIMEOUT, () => `Expected page URL to ${this.negated ? 'not ' : ''}match "${url}", but got "${last}"`);
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
async toHaveTitle(title, opts) {
|
|
353
|
+
return this._wrapAssertion('toHaveTitle', async () => {
|
|
354
|
+
let last = '';
|
|
355
|
+
await retryAssertion(async () => { try {
|
|
356
|
+
last = await this.page.title();
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
last = '';
|
|
360
|
+
} return last; }, (current) => this.matches(title instanceof RegExp ? title.test(current) : current === title), opts?.timeout ?? DEFAULT_TIMEOUT, () => `Expected page title to ${this.negated ? 'not ' : ''}match "${title}", but got "${last}"`);
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
// ─── WebLocatorAssertions ─────────────────────────────────────
|
|
365
|
+
// Standalone: every web matcher routes through Playwright's injected expect()
|
|
366
|
+
// (window.__mwInjected.expect) for byte-exact matcher semantics. Native
|
|
367
|
+
// LocatorAssertions and PageAssertions are unaffected.
|
|
368
|
+
class WebLocatorAssertions {
|
|
369
|
+
constructor(webLocator, negated) {
|
|
370
|
+
this.webLocator = webLocator;
|
|
371
|
+
this.negated = negated;
|
|
372
|
+
}
|
|
373
|
+
get not() {
|
|
374
|
+
return new WebLocatorAssertions(this.webLocator, !this.negated);
|
|
375
|
+
}
|
|
376
|
+
assertionTimeout(opts) {
|
|
377
|
+
return opts?.timeout ?? this.webLocator.expectTimeout ?? DEFAULT_TIMEOUT;
|
|
378
|
+
}
|
|
379
|
+
// Poll the injected matcher until matches !== isNot, or throw ExpectError.
|
|
380
|
+
runMatcher(method, params, opts) {
|
|
381
|
+
return wrapAssertion(this.webLocator._stepFn, this.negated, method, async () => {
|
|
382
|
+
const isNot = this.negated;
|
|
383
|
+
let received;
|
|
384
|
+
let missingReceived = false;
|
|
385
|
+
await retryAssertion(async () => {
|
|
386
|
+
const result = await this.webLocator._runInjectedExpect({ ...params, isNot, timeout: 0 });
|
|
387
|
+
received = result.received;
|
|
388
|
+
missingReceived = result.missingReceived ?? false;
|
|
389
|
+
return result.matches;
|
|
390
|
+
}, (matches) => matches !== isNot, this.assertionTimeout(opts), () => {
|
|
391
|
+
const got = missingReceived ? 'no element' : fmt(received);
|
|
392
|
+
return isNot
|
|
393
|
+
? `Expected ${method} NOT to match, but it did (received ${got})`
|
|
394
|
+
: `Expected ${method} to match, but it did not (received ${got})`;
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
toBeVisible(opts) {
|
|
399
|
+
return this.runMatcher('toBeVisible', { expression: 'to.be.visible' }, opts);
|
|
400
|
+
}
|
|
401
|
+
toBeHidden(opts) {
|
|
402
|
+
return this.runMatcher('toBeHidden', { expression: 'to.be.hidden' }, opts);
|
|
403
|
+
}
|
|
404
|
+
toBeEnabled(opts) {
|
|
405
|
+
return this.runMatcher('toBeEnabled', { expression: 'to.be.enabled' }, opts);
|
|
406
|
+
}
|
|
407
|
+
toBeDisabled(opts) {
|
|
408
|
+
return this.runMatcher('toBeDisabled', { expression: 'to.be.disabled' }, opts);
|
|
409
|
+
}
|
|
410
|
+
toBeEditable(opts) {
|
|
411
|
+
return this.runMatcher('toBeEditable', { expression: 'to.be.editable' }, opts);
|
|
412
|
+
}
|
|
413
|
+
toBeFocused(opts) {
|
|
414
|
+
return this.runMatcher('toBeFocused', { expression: 'to.be.focused' }, opts);
|
|
415
|
+
}
|
|
416
|
+
toBeAttached(opts) {
|
|
417
|
+
return this.runMatcher('toBeAttached', { expression: 'to.be.attached' }, opts);
|
|
418
|
+
}
|
|
419
|
+
toBeInViewport(opts) {
|
|
420
|
+
return this.runMatcher('toBeInViewport', { expression: 'to.be.in.viewport', expectedNumber: opts?.ratio }, opts);
|
|
421
|
+
}
|
|
422
|
+
toBeChecked(opts) {
|
|
423
|
+
return this.runMatcher('toBeChecked', { expression: 'to.be.checked', expectedValue: { checked: true, indeterminate: false } }, opts);
|
|
424
|
+
}
|
|
425
|
+
toBeEmpty(opts) {
|
|
426
|
+
return this.runMatcher('toBeEmpty', { expression: 'to.be.empty' }, opts);
|
|
427
|
+
}
|
|
428
|
+
toHaveText(expected, opts) {
|
|
429
|
+
return this.runMatcher('toHaveText', { expression: 'to.have.text', expectedText: [textValue(expected, { normalizeWhiteSpace: true })] }, opts);
|
|
430
|
+
}
|
|
431
|
+
toContainText(expected, opts) {
|
|
432
|
+
return this.runMatcher('toContainText', { expression: 'to.have.text', expectedText: [textValue(expected, { normalizeWhiteSpace: true, matchSubstring: true })] }, opts);
|
|
433
|
+
}
|
|
434
|
+
toHaveValue(expected, opts) {
|
|
435
|
+
return this.runMatcher('toHaveValue', { expression: 'to.have.value', expectedText: [textValue(expected)] }, opts);
|
|
436
|
+
}
|
|
437
|
+
toHaveCount(expected, opts) {
|
|
438
|
+
return this.runMatcher('toHaveCount', { expression: 'to.have.count', expectedNumber: expected }, opts);
|
|
439
|
+
}
|
|
440
|
+
toHaveAttribute(name, expected, opts) {
|
|
441
|
+
return this.runMatcher('toHaveAttribute', { expression: 'to.have.attribute.value', expressionArg: name, expectedText: [textValue(expected)] }, opts);
|
|
442
|
+
}
|
|
443
|
+
toHaveClass(expected, opts) {
|
|
444
|
+
return this.runMatcher('toHaveClass', { expression: 'to.have.class', expectedText: [textValue(expected)] }, opts);
|
|
445
|
+
}
|
|
446
|
+
toContainClass(expected, opts) {
|
|
447
|
+
return this.runMatcher('toContainClass', { expression: 'to.contain.class', expectedText: [textValue(expected)] }, opts);
|
|
448
|
+
}
|
|
449
|
+
toHaveCSS(name, expected, opts) {
|
|
450
|
+
return this.runMatcher('toHaveCSS', { expression: 'to.have.css', expressionArg: name, expectedText: [textValue(expected)] }, opts);
|
|
451
|
+
}
|
|
452
|
+
toHaveId(expected, opts) {
|
|
453
|
+
return this.runMatcher('toHaveId', { expression: 'to.have.id', expectedText: [textValue(expected)] }, opts);
|
|
454
|
+
}
|
|
455
|
+
toHaveJSProperty(name, expected, opts) {
|
|
456
|
+
return this.runMatcher('toHaveJSProperty', { expression: 'to.have.property', expressionArg: name, expectedValue: expected }, opts);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
300
459
|
function fmt(value) {
|
|
301
460
|
return typeof value === 'string' ? `"${value}"` : String(value);
|
|
302
461
|
}
|