@enekesabel/playwright-lite 0.3.0 → 0.4.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/LICENSES/JEST-EXPECT-BUNDLE-LICENSES.txt +627 -0
- package/README.md +39 -2
- package/THIRD_PARTY_NOTICES.txt +5 -1
- package/dist/index.d.mts +174 -2
- package/dist/index.mjs +8899 -3197
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -18,10 +18,31 @@ await page.getByRole("textbox", { name: "Name" }).fill("Ada");
|
|
|
18
18
|
await page.getByRole("button", { name: "Save" }).click();
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
+
## Assertions
|
|
22
|
+
|
|
23
|
+
`expect(locator)` supports `toBeAttached`, `toBeChecked`, `toBeDisabled`,
|
|
24
|
+
`toBeEditable`, `toBeEmpty`, `toBeEnabled`, `toBeFocused`, `toBeHidden`,
|
|
25
|
+
`toBeInViewport`, `toBeVisible`, `toContainText`, `toContainClass`,
|
|
26
|
+
`toHaveAccessibleDescription`, `toHaveAccessibleName`,
|
|
27
|
+
`toHaveAccessibleErrorMessage`, `toHaveAttribute`, `toHaveClass`,
|
|
28
|
+
`toHaveCount`, `toHaveCSS`, `toHaveId`, `toHaveJSProperty`, `toHaveRole`,
|
|
29
|
+
`toHaveText`, `toHaveValue`, `toHaveValues`, and the inline string form of
|
|
30
|
+
`toMatchAriaSnapshot`. `toHaveScreenshot` and ARIA snapshot forms that read,
|
|
31
|
+
write, or configure snapshot files are not available.
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { createPage, expect } from "@enekesabel/playwright-lite";
|
|
35
|
+
|
|
36
|
+
const page = createPage();
|
|
37
|
+
await expect(page.getByRole("button", { name: "Save" })).toBeEnabled();
|
|
38
|
+
await expect(page.locator(".notice")).toContainText("Saved");
|
|
39
|
+
```
|
|
40
|
+
|
|
21
41
|
## Runtime boundaries
|
|
22
42
|
|
|
23
43
|
- **Current document only.** No iframe traversal, `Frame`, or `FrameLocator` support.
|
|
24
44
|
- **Navigation ends execution.** `goto()` can start navigation, but replacing the document destroys the JavaScript context running your script. Automation cannot continue across a full-page navigation or reload.
|
|
45
|
+
- **No network-idle observation.** `networkidle` needs browser-wide request tracking, which this current-document runtime does not have.
|
|
25
46
|
- **Synthetic input.** Input events are not browser-trusted. Native keyboard behavior such as cursor movement, deletion, and focus traversal is not simulated.
|
|
26
47
|
- **No browser control.** No browser launch, browser contexts, or browser-level control over network traffic, downloads, or other tabs.
|
|
27
48
|
- **Content Security Policy still applies.** Evaluation callbacks need dynamic JavaScript evaluation to be allowed by the page's policy; the library does not bypass it.
|
|
@@ -47,6 +68,22 @@ Targets Playwright **1.62.1**. Statuses describe API compatibility within the ru
|
|
|
47
68
|
|
|
48
69
|
✅ Compatible · ⚠️ Partially compatible · ❌ Not implemented · 🚫 Intentionally excluded
|
|
49
70
|
|
|
71
|
+
### Expect
|
|
72
|
+
|
|
73
|
+
| API | Status | Notes |
|
|
74
|
+
| ------------------------------------------------------------------------------------------------------------------ | :----: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
75
|
+
| `API response assertions` | 🚫 | They operate on Playwright's Node-side API response objects, which have no in-document counterpart. |
|
|
76
|
+
| `Filesystem-backed snapshot assertions` | 🚫 | They require filesystem and test-runner state that is unavailable in the browser document. |
|
|
77
|
+
| `Locator assertions` | ✅ | Supports `toBeAttached`, `toBeChecked`, `toBeDisabled`, `toBeEditable`, `toBeEmpty`, `toBeEnabled`, `toBeFocused`, `toBeHidden`, `toBeInViewport`, `toBeVisible`, `toContainText`, `toContainClass`, `toHaveAccessibleDescription`, `toHaveAccessibleName`, `toHaveAccessibleErrorMessage`, `toHaveAttribute`, `toHaveClass`, `toHaveCount`, `toHaveCSS`, `toHaveId`, `toHaveJSProperty`, `toHaveRole`, `toHaveText`, `toHaveValue`, `toHaveValues`, and inline-string `toMatchAriaSnapshot`. `toHaveScreenshot` and file/config-driven ARIA snapshot forms are excluded. |
|
|
78
|
+
| [`expect(page).toHaveTitle()`](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-title) | ✅ | Supports string and RegExp expectations with `ignoreCase`, `timeout`, and `signal` options. |
|
|
79
|
+
| [`expect(page).toHaveURL()`](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-url) | ⚠️ | Supports string/glob, RegExp, URL predicates, and URLPattern values with `ignoreCase`, `timeout`, and `signal`; string expectations are matched against the current document because this runtime has no configured Playwright `baseURL`. |
|
|
80
|
+
| [`expect(value)`](https://playwright.dev/docs/test-assertions#generic-matchers) | ✅ | Supports Playwright's generic value matchers, asymmetric matching, `.not`, `.resolves`, `.rejects`, and custom messages. `expect(locator)` also supports the documented Locator assertions. |
|
|
81
|
+
| [`expect.configure()`](https://playwright.dev/docs/test-assertions#expectconfigure) | ⚠️ | Supports `timeout` and `message`. The `soft` option throws because playwright-lite has no Playwright Test failure-reporting context. |
|
|
82
|
+
| [`expect.extend()`](https://playwright.dev/docs/test-assertions#add-custom-matchers-using-expectextend) | ✅ | |
|
|
83
|
+
| [`expect.poll()`](https://playwright.dev/docs/test-assertions#expectpoll) | ✅ | |
|
|
84
|
+
| [`expect.soft()`](https://playwright.dev/docs/test-assertions#soft-assertions) | 🚫 | Throws because playwright-lite has no Playwright Test failure-reporting context. |
|
|
85
|
+
| [`toPass()`](https://playwright.dev/docs/test-assertions#expecttopass) | ✅ | |
|
|
86
|
+
|
|
50
87
|
### Page
|
|
51
88
|
|
|
52
89
|
| API | Status | Notes |
|
|
@@ -159,13 +196,13 @@ Targets Playwright **1.62.1**. Statuses describe API compatibility within the ru
|
|
|
159
196
|
| [`viewportSize`](https://playwright.dev/docs/api/class-page#page-viewport-size) | ❌ | |
|
|
160
197
|
| [`waitForEvent`](https://playwright.dev/docs/api/class-page#page-wait-for-event) | ❌ | |
|
|
161
198
|
| [`waitForFunction`](https://playwright.dev/docs/api/class-page#page-wait-for-function) | ⚠️ | The returned handle previews differently; see [ElementHandle compatibility](#elementhandle-compatibility). |
|
|
162
|
-
| [`waitForLoadState`](https://playwright.dev/docs/api/class-page#page-wait-for-load-state) |
|
|
199
|
+
| [`waitForLoadState`](https://playwright.dev/docs/api/class-page#page-wait-for-load-state) | ⚠️ | Rejects `networkidle`. |
|
|
163
200
|
| [`waitForNavigation`](https://playwright.dev/docs/api/class-page#page-wait-for-navigation) | ❌ | |
|
|
164
201
|
| [`waitForRequest`](https://playwright.dev/docs/api/class-page#page-wait-for-request) | ❌ | |
|
|
165
202
|
| [`waitForResponse`](https://playwright.dev/docs/api/class-page#page-wait-for-response) | ❌ | |
|
|
166
203
|
| [`waitForSelector`](https://playwright.dev/docs/api/class-page#page-wait-for-selector) | ⚠️ | Returned `ElementHandle` methods and options differ; see [ElementHandle compatibility](#elementhandle-compatibility). |
|
|
167
204
|
| [`waitForTimeout`](https://playwright.dev/docs/api/class-page#page-wait-for-timeout) | ✅ | |
|
|
168
|
-
| [`waitForURL`](https://playwright.dev/docs/api/class-page#page-wait-for-url) |
|
|
205
|
+
| [`waitForURL`](https://playwright.dev/docs/api/class-page#page-wait-for-url) | ⚠️ | Rejects `waitUntil: "networkidle"`. |
|
|
169
206
|
| [`workers`](https://playwright.dev/docs/api/class-page#page-workers) | ❌ | |
|
|
170
207
|
|
|
171
208
|
### Locator
|
package/THIRD_PARTY_NOTICES.txt
CHANGED
|
@@ -2,10 +2,14 @@ playwright-lite is MIT licensed. Included third-party code retains its own licen
|
|
|
2
2
|
|
|
3
3
|
Playwright
|
|
4
4
|
Copyright Microsoft Corporation and contributors.
|
|
5
|
-
The browser injected and utility scripts, protocol serializers, copied upstream tests, keyboard layout, and other identified Playwright-derived code are distributed under Apache License 2.0.
|
|
5
|
+
The browser injected and utility scripts, protocol serializers, copied upstream tests, keyboard layout, public expect wrapper, and other identified Playwright-derived code are distributed under Apache License 2.0.
|
|
6
6
|
The pinned upstream revision is recorded in tests/upstream/corpus.ts. The injected script is generated with the upstream build tool, then bundled with a browser-side Page and Locator implementation. The keyboard layout retains its original data with local typing helpers. Copied upstream test specifications are unchanged.
|
|
7
7
|
See LICENSES/PLAYWRIGHT-LICENSE.txt and the accompanying upstream notices in LICENSES.
|
|
8
8
|
|
|
9
|
+
Jest expect components and their dependencies
|
|
10
|
+
Copyright Meta Platforms, Inc. and affiliates, the Jest project contributors, and the respective dependency authors.
|
|
11
|
+
The generic matcher library is based on Playwright's pinned Jest-derived expect sources. Its bundled browser dependencies retain their MIT licenses. See LICENSES/JEST-EXPECT-BUNDLE-LICENSES.txt.
|
|
12
|
+
|
|
9
13
|
YAML
|
|
10
14
|
Copyright 2018, 2019, 2020 Eemeli Aro and contributors.
|
|
11
15
|
Bundled under the ISC license. See LICENSES/YAML-LICENSE.txt.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,179 @@
|
|
|
1
|
-
import { Page, PlaywrightTestOptions } from "@playwright/test";
|
|
1
|
+
import { Locator, Page, PlaywrightTestOptions } from "@playwright/test";
|
|
2
|
+
//#region src/expect.d.ts
|
|
3
|
+
interface AsymmetricMatcher {
|
|
4
|
+
asymmetricMatch(other: unknown): boolean;
|
|
5
|
+
}
|
|
6
|
+
interface AsymmetricMatchers {
|
|
7
|
+
any(expectedObject: unknown): AsymmetricMatcher;
|
|
8
|
+
anything(): AsymmetricMatcher;
|
|
9
|
+
arrayContaining(sample: unknown[]): AsymmetricMatcher;
|
|
10
|
+
arrayOf(sample: unknown): AsymmetricMatcher;
|
|
11
|
+
closeTo(expected: number, precision?: number): AsymmetricMatcher;
|
|
12
|
+
objectContaining(sample: Record<string, unknown>): AsymmetricMatcher;
|
|
13
|
+
stringContaining(expected: string): AsymmetricMatcher;
|
|
14
|
+
stringMatching(expected: string | RegExp): AsymmetricMatcher;
|
|
15
|
+
}
|
|
16
|
+
interface GenericAssertions<R> {
|
|
17
|
+
toBe(expected: unknown): R;
|
|
18
|
+
toBeCloseTo(expected: number, precision?: number): R;
|
|
19
|
+
toBeDefined(): R;
|
|
20
|
+
toBeFalsy(): R;
|
|
21
|
+
toBeGreaterThan(expected: number | bigint): R;
|
|
22
|
+
toBeGreaterThanOrEqual(expected: number | bigint): R;
|
|
23
|
+
toBeInstanceOf(expected: Function): R;
|
|
24
|
+
toBeLessThan(expected: number | bigint): R;
|
|
25
|
+
toBeLessThanOrEqual(expected: number | bigint): R;
|
|
26
|
+
toBeNaN(): R;
|
|
27
|
+
toBeNull(): R;
|
|
28
|
+
toBeTruthy(): R;
|
|
29
|
+
toBeUndefined(): R;
|
|
30
|
+
toContain(expected: unknown): R;
|
|
31
|
+
toContainEqual(expected: unknown): R;
|
|
32
|
+
toEqual(expected: unknown): R;
|
|
33
|
+
toHaveLength(expected: number): R;
|
|
34
|
+
toHaveProperty(path: string | string[], value?: unknown): R;
|
|
35
|
+
toMatch(expected: string | RegExp): R;
|
|
36
|
+
toMatchObject(expected: Record<string, unknown> | unknown[]): R;
|
|
37
|
+
toStrictEqual(expected: unknown): R;
|
|
38
|
+
toThrow(expected?: unknown): R;
|
|
39
|
+
toThrowError(expected?: unknown): R;
|
|
40
|
+
}
|
|
41
|
+
type LocatorAssertionOptions = {
|
|
42
|
+
signal?: AbortSignal;
|
|
43
|
+
timeout?: number;
|
|
44
|
+
};
|
|
45
|
+
type TextAssertionOptions = LocatorAssertionOptions & {
|
|
46
|
+
ignoreCase?: boolean;
|
|
47
|
+
};
|
|
48
|
+
type AriaRole = Parameters<Locator["getByRole"]>[0];
|
|
49
|
+
/** The browser-safe subset of Playwright's LocatorAssertions. */
|
|
50
|
+
interface LocatorAssertions {
|
|
51
|
+
toBeAttached(options?: LocatorAssertionOptions & {
|
|
52
|
+
attached?: boolean;
|
|
53
|
+
}): Promise<void>;
|
|
54
|
+
toBeChecked(options?: LocatorAssertionOptions & {
|
|
55
|
+
checked?: boolean;
|
|
56
|
+
indeterminate?: boolean;
|
|
57
|
+
}): Promise<void>;
|
|
58
|
+
toBeDisabled(options?: LocatorAssertionOptions): Promise<void>;
|
|
59
|
+
toBeEditable(options?: LocatorAssertionOptions & {
|
|
60
|
+
editable?: boolean;
|
|
61
|
+
}): Promise<void>;
|
|
62
|
+
toBeEmpty(options?: LocatorAssertionOptions): Promise<void>;
|
|
63
|
+
toBeEnabled(options?: LocatorAssertionOptions & {
|
|
64
|
+
enabled?: boolean;
|
|
65
|
+
}): Promise<void>;
|
|
66
|
+
toBeFocused(options?: LocatorAssertionOptions): Promise<void>;
|
|
67
|
+
toBeHidden(options?: LocatorAssertionOptions): Promise<void>;
|
|
68
|
+
toBeInViewport(options?: LocatorAssertionOptions & {
|
|
69
|
+
ratio?: number;
|
|
70
|
+
}): Promise<void>;
|
|
71
|
+
toBeVisible(options?: LocatorAssertionOptions & {
|
|
72
|
+
visible?: boolean;
|
|
73
|
+
}): Promise<void>;
|
|
74
|
+
toContainText(expected: string | RegExp | ReadonlyArray<string | RegExp>, options?: TextAssertionOptions & {
|
|
75
|
+
useInnerText?: boolean;
|
|
76
|
+
}): Promise<void>;
|
|
77
|
+
toContainClass(expected: string | ReadonlyArray<string>, options?: LocatorAssertionOptions): Promise<void>;
|
|
78
|
+
toHaveAccessibleDescription(expected: string | RegExp, options?: TextAssertionOptions): Promise<void>;
|
|
79
|
+
toHaveAccessibleName(expected: string | RegExp, options?: TextAssertionOptions): Promise<void>;
|
|
80
|
+
toHaveAccessibleErrorMessage(expected: string | RegExp, options?: TextAssertionOptions): Promise<void>;
|
|
81
|
+
toHaveAttribute(name: string, options?: LocatorAssertionOptions): Promise<void>;
|
|
82
|
+
toHaveAttribute(name: string, expected: string | RegExp, options?: TextAssertionOptions): Promise<void>;
|
|
83
|
+
toHaveClass(expected: string | RegExp | ReadonlyArray<string | RegExp>, options?: LocatorAssertionOptions): Promise<void>;
|
|
84
|
+
toHaveCount(expected: number, options?: LocatorAssertionOptions): Promise<void>;
|
|
85
|
+
toHaveCSS(name: string, expected: string | RegExp, options?: LocatorAssertionOptions & {
|
|
86
|
+
pseudo?: string;
|
|
87
|
+
}): Promise<void>;
|
|
88
|
+
toHaveId(expected: string | RegExp, options?: LocatorAssertionOptions): Promise<void>;
|
|
89
|
+
toHaveJSProperty(name: string, expected: unknown, options?: LocatorAssertionOptions): Promise<void>;
|
|
90
|
+
toHaveRole(expected: AriaRole, options?: LocatorAssertionOptions): Promise<void>;
|
|
91
|
+
toHaveText(expected: string | RegExp | ReadonlyArray<string | RegExp>, options?: TextAssertionOptions & {
|
|
92
|
+
useInnerText?: boolean;
|
|
93
|
+
}): Promise<void>;
|
|
94
|
+
toHaveValue(expected: string | RegExp, options?: LocatorAssertionOptions): Promise<void>;
|
|
95
|
+
toHaveValues(expected: ReadonlyArray<string | RegExp>, options?: LocatorAssertionOptions): Promise<void>;
|
|
96
|
+
toMatchAriaSnapshot(expected: string, options?: LocatorAssertionOptions): Promise<void>;
|
|
97
|
+
}
|
|
98
|
+
type PageURLExpected = Parameters<Page["waitForURL"]>[0];
|
|
99
|
+
type PageAssertionOptions = {
|
|
100
|
+
signal?: AbortSignal;
|
|
101
|
+
timeout?: number;
|
|
102
|
+
};
|
|
103
|
+
type PageURLAssertionOptions = PageAssertionOptions & {
|
|
104
|
+
ignoreCase?: boolean;
|
|
105
|
+
};
|
|
106
|
+
interface PageAssertions {
|
|
107
|
+
toHaveTitle(expected: string | RegExp, options?: PageAssertionOptions & {
|
|
108
|
+
ignoreCase?: boolean;
|
|
109
|
+
}): Promise<void>;
|
|
110
|
+
toHaveURL(expected: PageURLExpected, options?: PageURLAssertionOptions): Promise<void>;
|
|
111
|
+
}
|
|
112
|
+
interface ExpectMatcherUtils {
|
|
113
|
+
matcherHint(matcherName: string, received?: unknown, expected?: unknown, options?: Record<string, unknown>): string;
|
|
114
|
+
printDiffOrStringify(expected: unknown, received: unknown, expectedLabel: string, receivedLabel: string, expand: boolean): string;
|
|
115
|
+
printExpected(value: unknown): string;
|
|
116
|
+
printReceived(value: unknown): string;
|
|
117
|
+
printWithType<T>(name: string, value: T, print: (value: T) => string): string;
|
|
118
|
+
diff(a: unknown, b: unknown): string | null;
|
|
119
|
+
stringify(value: unknown, maxDepth?: number, maxWidth?: number): string;
|
|
120
|
+
EXPECTED_COLOR(value: string): string;
|
|
121
|
+
}
|
|
122
|
+
interface ExpectMatcherState {
|
|
123
|
+
isNot: boolean;
|
|
124
|
+
promise: "rejects" | "resolves" | "";
|
|
125
|
+
timeout: number;
|
|
126
|
+
utils: ExpectMatcherUtils;
|
|
127
|
+
}
|
|
128
|
+
interface MatcherResult {
|
|
129
|
+
message: () => string;
|
|
130
|
+
pass: boolean;
|
|
131
|
+
name?: string;
|
|
132
|
+
expected?: unknown;
|
|
133
|
+
actual?: unknown;
|
|
134
|
+
ariaSnapshot?: string;
|
|
135
|
+
log?: string[];
|
|
136
|
+
timeout?: number;
|
|
137
|
+
}
|
|
138
|
+
type ToUserMatcher<F, R> = F extends ((received: any, ...args: infer A) => infer M) ? (...args: A) => M extends PromiseLike<unknown> ? Promise<void> : R : never;
|
|
139
|
+
type UserMatchers<E, R, T> = { [K in keyof E as E[K] extends ((received: T, ...args: any[]) => any) ? K : never]: ToUserMatcher<E[K], R>; };
|
|
140
|
+
type FunctionAssertions = {
|
|
141
|
+
toPass(options?: {
|
|
142
|
+
timeout?: number;
|
|
143
|
+
intervals?: number[];
|
|
144
|
+
}): Promise<void>;
|
|
145
|
+
};
|
|
146
|
+
type Matchers<R, T, ExtendedMatchers> = {
|
|
147
|
+
not: Matchers<R, T, ExtendedMatchers>;
|
|
148
|
+
resolves: Matchers<Promise<void>, Awaited<T>, ExtendedMatchers>;
|
|
149
|
+
rejects: Matchers<Promise<void>, any, ExtendedMatchers>;
|
|
150
|
+
} & GenericAssertions<R> & (T extends Locator ? LocatorAssertions : Record<never, never>) & (T extends Page ? PageAssertions : Record<never, never>) & (T extends ((...args: never[]) => unknown) ? FunctionAssertions : Record<never, never>) & UserMatchers<T extends Page ? Omit<ExtendedMatchers, keyof PageAssertions> : ExtendedMatchers, R, T>;
|
|
151
|
+
type PollMatchers<T, ExtendedMatchers> = {
|
|
152
|
+
not: PollMatchers<T, ExtendedMatchers>;
|
|
153
|
+
} & GenericAssertions<Promise<void>> & UserMatchers<ExtendedMatchers, Promise<void>, T>;
|
|
154
|
+
type Expect<ExtendedMatchers = Record<never, never>> = {
|
|
155
|
+
<T = unknown>(actual: T, messageOrOptions?: string | {
|
|
156
|
+
message?: string;
|
|
157
|
+
}): Matchers<void, T, ExtendedMatchers>;
|
|
158
|
+
poll<T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | {
|
|
159
|
+
message?: string;
|
|
160
|
+
timeout?: number;
|
|
161
|
+
intervals?: number[];
|
|
162
|
+
}): PollMatchers<T, ExtendedMatchers>;
|
|
163
|
+
extend<MoreMatchers extends Record<string, (this: ExpectMatcherState, received: any, ...args: any[]) => MatcherResult | Promise<MatcherResult>>>(matchers: MoreMatchers): Expect<ExtendedMatchers & MoreMatchers>;
|
|
164
|
+
configure(configuration: {
|
|
165
|
+
message?: string;
|
|
166
|
+
soft?: boolean;
|
|
167
|
+
timeout?: number;
|
|
168
|
+
}): Expect<ExtendedMatchers>;
|
|
169
|
+
getState(): object;
|
|
170
|
+
not: Omit<AsymmetricMatchers, "any" | "anything">;
|
|
171
|
+
} & AsymmetricMatchers;
|
|
172
|
+
declare const expect: Expect;
|
|
173
|
+
//#endregion
|
|
2
174
|
//#region src/index.d.ts
|
|
3
175
|
type CreatePageOptions = Partial<Pick<PlaywrightTestOptions, "testIdAttribute" | "actionTimeout" | "navigationTimeout">>;
|
|
4
176
|
/** Creates a Page for the current browser window. Omitted settings keep the runtime defaults. */
|
|
5
177
|
declare function createPage(options?: CreatePageOptions): Page;
|
|
6
178
|
//#endregion
|
|
7
|
-
export { CreatePageOptions, createPage };
|
|
179
|
+
export { CreatePageOptions, type Expect, createPage, expect };
|