@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/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
@@ -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 };