effect-playwright 0.1.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/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ ISC License
2
+
3
+ Copyright 2025 Jobflow GmbH
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # effect-playwright
2
+
3
+ [![GitHub License](https://img.shields.io/github/license/Jobflow-io/effect-playwright)](https://github.com/Jobflow-io/effect-playwright/blob/main/LICENSE)
4
+ [![Effect: yes](https://img.shields.io/badge/effect-yes-blue)](https://effect.website/)
5
+
6
+ A Playwright wrapper for the Effect ecosystem. This library provides a set of services and layers to interact with Playwright in a type-safe way using Effect.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ pnpm add effect-playwright playwright-core
12
+ ```
13
+
14
+ or
15
+
16
+ ```bash
17
+ npm install effect-playwright playwright-core
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ```ts
23
+ import { Playwright } from "effect-playwright";
24
+ import { Effect } from "effect";
25
+ import { chromium } from "playwright-core";
26
+
27
+ const program = Effect.gen(function* () {
28
+ const playwright = yield* Playwright;
29
+ const browser = yield* playwright.launchScoped(chromium);
30
+ const page = yield* browser.newPage();
31
+
32
+ yield* page.goto("https://example.com");
33
+ const title = yield* page.title;
34
+ console.log(`Page title: ${title}`);
35
+ }).pipe(Effect.scoped, Effect.provide(Playwright.layer));
36
+
37
+ await Effect.runPromise(program);
38
+ ```
39
+
40
+ ## Managing Lifecycle
41
+
42
+ Using `launchScoped` is the recommended way to manage the browser lifecycle. It ensures that the browser is closed automatically when the effect's scope ends, preventing resource leaks.
43
+
44
+ ```ts
45
+ const program = Effect.gen(function* () {
46
+ const playwright = yield* Playwright;
47
+ const browser = yield* playwright.launchScoped(chromium);
48
+ // Browser will be closed automatically after this block
49
+ }).pipe(Effect.scoped);
50
+ ```
51
+
52
+ ## PlaywrightEnvironment (Experimental)
53
+
54
+ The `PlaywrightEnvironment` simplifies setup by allowing you to configure the browser type and launch options once and reuse them across your application.
55
+
56
+ ### Usage
57
+
58
+ ```ts
59
+ import { PlaywrightBrowser } from "effect-playwright";
60
+ import { PlaywrightEnvironment } from "effect-playwright/experimental";
61
+ import { Effect } from "effect";
62
+ import { chromium } from "playwright-core";
63
+
64
+ const liveLayer = PlaywrightEnvironment.layer(chromium, {
65
+ headless: true /** any other launch options */,
66
+ });
67
+
68
+ const program = Effect.gen(function* () {
69
+ const browser = yield* PlaywrightBrowser;
70
+ const page = yield* browser.newPage();
71
+
72
+ yield* page.goto("https://example.com");
73
+ }).pipe(PlaywrightEnvironment.withBrowser);
74
+
75
+ await Effect.runPromise(program.pipe(Effect.provide(liveLayer)));
76
+ ```
77
+
78
+ ## Accessing Native Playwright
79
+
80
+ If you need to access functionality from the underlying Playwright objects that isn't directly exposed, you can use the `use` method available on most services/objects (browsers, pages, locators).
81
+
82
+ ```ts
83
+ import { Playwright } from "effect-playwright";
84
+ import { Effect } from "effect";
85
+ import { chromium } from "playwright-core";
86
+
87
+ const program = Effect.gen(function* () {
88
+ const playwright = yield* Playwright;
89
+ const browser = yield* playwright.launchScoped(chromium);
90
+ const page = yield* browser.newPage();
91
+
92
+ // Use the native Playwright Page object
93
+ const screenshot = yield* page.use((p) => p.screenshot());
94
+ });
95
+ ```
96
+
97
+ ## Error Handling
98
+
99
+ All methods return effects that can fail with a `PlaywrightError`. This error wraps the original error from Playwright.
100
+ Note that Playwright does not support interruption, so `Effect.timeout` or similar code does not behave like you
101
+ might expect. Playwright provides its own `timeout` option for almost every method.
@@ -0,0 +1,18 @@
1
+ //#region rolldown:runtime
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, symbols) => {
4
+ let target = {};
5
+ for (var name in all) {
6
+ __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
9
+ });
10
+ }
11
+ if (symbols) {
12
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
13
+ }
14
+ return target;
15
+ };
16
+
17
+ //#endregion
18
+ export { __exportAll as t };
@@ -0,0 +1,74 @@
1
+ import { d as PlaywrightError, o as PlaywrightBrowser } from "../index-aR0Fa_4Y.mjs";
2
+ import { Context, Effect, Layer } from "effect";
3
+ import { BrowserType, LaunchOptions } from "playwright-core";
4
+ import { Scope as Scope$1 } from "effect/Scope";
5
+
6
+ //#region src/experimental/environment.d.ts
7
+ declare namespace environment_d_exports {
8
+ export { PlaywrightEnvironment, layer, withBrowser };
9
+ }
10
+ declare const PlaywrightEnvironment_base: Context.TagClass<PlaywrightEnvironment, "effect-playwright/experimental/PlaywrightEnvironment", {
11
+ browser: Effect.Effect<typeof PlaywrightBrowser.Service, PlaywrightError, Scope$1>;
12
+ }>;
13
+ /**
14
+ * Most of the time you want to use the same kind of browser and configuration every time you use Playwright.
15
+ * `PlaywrightEnvironment` is a service that allows you to configure how browsers are launched once. You can then
16
+ * use {@link PlaywrightEnvironment.browser} to start browsers scoped to the current lifetime. They will be closed when the scope is closed.
17
+ *
18
+ * You can use {@link PlaywrightEnvironment.withBrowser} to provide the `PlaywrightBrowser` service to the wrapped effect. This
19
+ * also allows you to re-use the same browser as many times as you want.
20
+ *
21
+ * @since 0.1.0
22
+ * @category tag
23
+ */
24
+ declare class PlaywrightEnvironment extends PlaywrightEnvironment_base {}
25
+ /**
26
+ * Creates a Layer that initializes the `PlaywrightEnvironment`.
27
+ *
28
+ * @example
29
+ *
30
+ * ```ts
31
+ * import { PlaywrightEnvironment } from "effect-playwright/experimental";
32
+ * import { chromium } from "playwright-core";
33
+ *
34
+ * const playwrightEnv = PlaywrightEnvironment.layer(chromium);
35
+ *
36
+ * // use the layer
37
+ * const program = Effect.gen(function* () {
38
+ * const browser = yield* PlaywrightEnvironment.browser;
39
+ * const page = yield* browser.newPage();
40
+ * yield* page.goto("https://example.com");
41
+ * }).pipe(PlaywrightEnvironment.withBrowser, Effect.provide(playwrightEnv));
42
+ * ```
43
+ *
44
+ * @param browser - The Playwright BrowserType implementation (e.g. `chromium`, `firefox`, `webkit`).
45
+ * @param launchOptions - Optional configuration for launching the browser (e.g. headless, args).
46
+ *
47
+ * @since 0.1.0
48
+ * @category layer
49
+ */
50
+ declare const layer: (browser: BrowserType, launchOptions?: LaunchOptions) => Layer.Layer<PlaywrightEnvironment, never, never>;
51
+ /**
52
+ * Provides a scoped `PlaywrightBrowser` service, allowing you to access the browser from the context (e.g. by yielding `PlaywrightBrowser`).
53
+ *
54
+ * You will need to provide the `PlaywrightEnvironment` layer first.
55
+ *
56
+ * @example
57
+ *
58
+ * ```ts
59
+ * import { PlaywrightEnvironment } from "effect-playwright/experimental";
60
+ * import { chromium } from "playwright-core";
61
+ *
62
+ * const layer = PlaywrightEnvironment.layer(chromium);
63
+ * const program = Effect.gen(function* () {
64
+ * const browser = yield* PlaywrightBrowser;
65
+ * const page = yield* browser.newPage();
66
+ * yield* page.goto("https://example.com");
67
+ * }).pipe(PlaywrightEnvironment.withBrowser);
68
+ * ```
69
+ *
70
+ * @since 0.1.0
71
+ */
72
+ declare const withBrowser: <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, PlaywrightError | E, PlaywrightEnvironment | Exclude<R, PlaywrightBrowser>>;
73
+ //#endregion
74
+ export { environment_d_exports as PlaywrightEnvironment };
@@ -0,0 +1,77 @@
1
+ import { t as __exportAll } from "../chunk-BiucMVzj.mjs";
2
+ import { n as PlaywrightBrowser, t as Playwright } from "../src-DveiwW4g.mjs";
3
+ import { Context, Effect, Layer } from "effect";
4
+
5
+ //#region src/experimental/environment.ts
6
+ var environment_exports = /* @__PURE__ */ __exportAll({
7
+ PlaywrightEnvironment: () => PlaywrightEnvironment,
8
+ layer: () => layer,
9
+ withBrowser: () => withBrowser
10
+ });
11
+ /**
12
+ * Most of the time you want to use the same kind of browser and configuration every time you use Playwright.
13
+ * `PlaywrightEnvironment` is a service that allows you to configure how browsers are launched once. You can then
14
+ * use {@link PlaywrightEnvironment.browser} to start browsers scoped to the current lifetime. They will be closed when the scope is closed.
15
+ *
16
+ * You can use {@link PlaywrightEnvironment.withBrowser} to provide the `PlaywrightBrowser` service to the wrapped effect. This
17
+ * also allows you to re-use the same browser as many times as you want.
18
+ *
19
+ * @since 0.1.0
20
+ * @category tag
21
+ */
22
+ var PlaywrightEnvironment = class extends Context.Tag("effect-playwright/experimental/PlaywrightEnvironment")() {};
23
+ /**
24
+ * Creates a Layer that initializes the `PlaywrightEnvironment`.
25
+ *
26
+ * @example
27
+ *
28
+ * ```ts
29
+ * import { PlaywrightEnvironment } from "effect-playwright/experimental";
30
+ * import { chromium } from "playwright-core";
31
+ *
32
+ * const playwrightEnv = PlaywrightEnvironment.layer(chromium);
33
+ *
34
+ * // use the layer
35
+ * const program = Effect.gen(function* () {
36
+ * const browser = yield* PlaywrightEnvironment.browser;
37
+ * const page = yield* browser.newPage();
38
+ * yield* page.goto("https://example.com");
39
+ * }).pipe(PlaywrightEnvironment.withBrowser, Effect.provide(playwrightEnv));
40
+ * ```
41
+ *
42
+ * @param browser - The Playwright BrowserType implementation (e.g. `chromium`, `firefox`, `webkit`).
43
+ * @param launchOptions - Optional configuration for launching the browser (e.g. headless, args).
44
+ *
45
+ * @since 0.1.0
46
+ * @category layer
47
+ */
48
+ const layer = (browser, launchOptions) => {
49
+ return Layer.effect(PlaywrightEnvironment, Playwright.pipe(Effect.map((playwright) => {
50
+ return PlaywrightEnvironment.of({ browser: playwright.launchScoped(browser, launchOptions) });
51
+ })).pipe(Effect.provide(Playwright.layer)));
52
+ };
53
+ /**
54
+ * Provides a scoped `PlaywrightBrowser` service, allowing you to access the browser from the context (e.g. by yielding `PlaywrightBrowser`).
55
+ *
56
+ * You will need to provide the `PlaywrightEnvironment` layer first.
57
+ *
58
+ * @example
59
+ *
60
+ * ```ts
61
+ * import { PlaywrightEnvironment } from "effect-playwright/experimental";
62
+ * import { chromium } from "playwright-core";
63
+ *
64
+ * const layer = PlaywrightEnvironment.layer(chromium);
65
+ * const program = Effect.gen(function* () {
66
+ * const browser = yield* PlaywrightBrowser;
67
+ * const page = yield* browser.newPage();
68
+ * yield* page.goto("https://example.com");
69
+ * }).pipe(PlaywrightEnvironment.withBrowser);
70
+ * ```
71
+ *
72
+ * @since 0.1.0
73
+ */
74
+ const withBrowser = Effect.provide(PlaywrightEnvironment.pipe(Effect.map((e) => e.browser), Effect.flatten, Layer.scoped(PlaywrightBrowser)));
75
+
76
+ //#endregion
77
+ export { environment_exports as PlaywrightEnvironment };
@@ -0,0 +1,584 @@
1
+ import { Context, Effect, Layer, Scope, Stream } from "effect";
2
+ import { Browser, BrowserContext, BrowserType, ConnectOverCDPOptions, ConsoleMessage, Dialog, Download, ElementHandle, FileChooser, Frame, JSHandle, Locator, Page, Request, Response, WebSocket, Worker, chromium } from "playwright-core";
3
+ import { Scope as Scope$1 } from "effect/Scope";
4
+ import * as effect_Types0 from "effect/Types";
5
+ import * as effect_Cause0 from "effect/Cause";
6
+
7
+ //#region src/errors.d.ts
8
+ type PlaywrightErrorReason = "Timeout" | "Unknown";
9
+ declare const PlaywrightError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
10
+ readonly _tag: "PlaywrightError";
11
+ } & Readonly<A>;
12
+ declare class PlaywrightError extends PlaywrightError_base<{
13
+ reason: PlaywrightErrorReason;
14
+ cause: unknown;
15
+ }> {}
16
+ //#endregion
17
+ //#region src/playwright-types.d.ts
18
+ /**
19
+ * Extracted from `playwright-core/types/structs.d.ts` because it is not exported over the package boundary.
20
+ * These types are necessary to correctly type `evaluate` functions that unwrap handles.
21
+ */
22
+ type NoHandles<Arg> = Arg extends JSHandle ? never : Arg extends object ? { [Key in keyof Arg]: NoHandles<Arg[Key]> } : Arg;
23
+ type Unboxed<Arg> = Arg extends ElementHandle<infer T> ? T : Arg extends JSHandle<infer T> ? T : Arg extends NoHandles<Arg> ? Arg : Arg extends [infer A0] ? [Unboxed<A0>] : Arg extends [infer A0, infer A1] ? [Unboxed<A0>, Unboxed<A1>] : Arg extends [infer A0, infer A1, infer A2] ? [Unboxed<A0>, Unboxed<A1>, Unboxed<A2>] : Arg extends [infer A0, infer A1, infer A2, infer A3] ? [Unboxed<A0>, Unboxed<A1>, Unboxed<A2>, Unboxed<A3>] : Arg extends Array<infer T> ? Array<Unboxed<T>> : Arg extends object ? { [Key in keyof Arg]: Unboxed<Arg[Key]> } : Arg;
24
+ type PageFunction<Arg, R> = string | ((arg: Unboxed<Arg>) => R | Promise<R>);
25
+ //#endregion
26
+ //#region src/locator.d.ts
27
+ /**
28
+ * Interface for a Playwright locator.
29
+ * @category model
30
+ */
31
+ interface PlaywrightLocatorService {
32
+ /**
33
+ * Clicks the element.
34
+ *
35
+ * @see {@link Locator.click}
36
+ * @since 0.1.0
37
+ */
38
+ readonly click: (options?: Parameters<Locator["click"]>[0]) => Effect.Effect<void, PlaywrightError>;
39
+ /**
40
+ * Fills the input field.
41
+ *
42
+ * @see {@link Locator.fill}
43
+ * @since 0.1.0
44
+ */
45
+ readonly fill: (value: string, options?: Parameters<Locator["fill"]>[1]) => Effect.Effect<void, PlaywrightError>;
46
+ /**
47
+ * Gets an attribute value.
48
+ *
49
+ * @see {@link Locator.getAttribute}
50
+ * @since 0.1.0
51
+ */
52
+ readonly getAttribute: (name: string, options?: Parameters<Locator["getAttribute"]>[1]) => Effect.Effect<string | null, PlaywrightError>;
53
+ /**
54
+ * Gets the inner text.
55
+ *
56
+ * @see {@link Locator.innerText}
57
+ * @since 0.1.0
58
+ */
59
+ readonly innerText: (options?: Parameters<Locator["innerText"]>[0]) => Effect.Effect<string, PlaywrightError>;
60
+ /**
61
+ * Gets the inner HTML.
62
+ *
63
+ * @see {@link Locator.innerHTML}
64
+ * @since 0.1.0
65
+ */
66
+ readonly innerHTML: (options?: Parameters<Locator["innerHTML"]>[0]) => Effect.Effect<string, PlaywrightError>;
67
+ /**
68
+ * Gets the input value.
69
+ *
70
+ * @see {@link Locator.inputValue}
71
+ * @since 0.1.0
72
+ */
73
+ readonly inputValue: (options?: Parameters<Locator["inputValue"]>[0]) => Effect.Effect<string, PlaywrightError>;
74
+ /**
75
+ * Gets the text content.
76
+ *
77
+ * @see {@link Locator.textContent}
78
+ * @since 0.1.0
79
+ */
80
+ readonly textContent: (options?: Parameters<Locator["textContent"]>[0]) => Effect.Effect<string | null, PlaywrightError>;
81
+ /**
82
+ * Counts the number of matched elements.
83
+ *
84
+ * @see {@link Locator.count}
85
+ * @since 0.1.0
86
+ */
87
+ readonly count: Effect.Effect<number, PlaywrightError>;
88
+ /**
89
+ * Returns a locator that points to the first matched element.
90
+ * @see {@link Locator.first}
91
+ * @since 0.1.0
92
+ */
93
+ readonly first: () => PlaywrightLocatorService;
94
+ /**
95
+ * Returns a locator that points to the last matched element.
96
+ *
97
+ * @see {@link Locator.last}
98
+ * @since 0.1.0
99
+ */
100
+ readonly last: () => PlaywrightLocatorService;
101
+ /**
102
+ * Returns a locator that points to the nth matched element.
103
+ *
104
+ * @see {@link Locator.nth}
105
+ * @since 0.1.0
106
+ */
107
+ readonly nth: (index: number) => PlaywrightLocatorService;
108
+ /**
109
+ * Evaluates a function on the matched element.
110
+ *
111
+ * @example
112
+ * ```ts
113
+ * import { PlaywrightBrowser } from "effect-playwright";
114
+ * import { PlaywrightEnvironment } from "effect-playwright/experimental";
115
+ * import { chromium } from "@playwright/test";
116
+ * import { Effect } from "effect";
117
+ *
118
+ * const program = Effect.gen(function* () {
119
+ * const browser = yield* PlaywrightBrowser;
120
+ * const page = yield* browser.newPage();
121
+ * const locator = yield* page.locator("button");
122
+ * const buttonContent = yield* locator.evaluate((button) => button.textContent());
123
+ * }).pipe(PlaywrightEnvironment.provideBrowser, Effect.provide(PlaywrightEnvironment.layer(chromium)));
124
+ * ```
125
+ *
126
+ * @see {@link Locator.evaluate}
127
+ * @since 0.1.0
128
+ */
129
+ readonly evaluate: <R, Arg = void, E extends SVGElement | HTMLElement = SVGElement | HTMLElement>(pageFunction: (element: E, arg: Unboxed<Arg>) => R | Promise<R>, arg?: Arg, options?: {
130
+ timeout?: number;
131
+ }) => Effect.Effect<R, PlaywrightError>;
132
+ /**
133
+ * A generic utility to execute any promise-based method on the underlying Playwright `Locator`.
134
+ * Can be used to access any Locator functionality not directly exposed by this service.
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const isVisible = yield* locator.use((l) => l.isVisible());
139
+ * ```
140
+ *
141
+ * @param f - A function that takes the Playwright `Locator` and returns a `Promise`.
142
+ * @returns An effect that wraps the promise and returns its result.
143
+ * @see {@link Locator}
144
+ * @since 0.1.0
145
+ */
146
+ readonly use: <T$1>(f: (locator: Locator) => Promise<T$1>) => Effect.Effect<T$1, PlaywrightError>;
147
+ }
148
+ declare const PlaywrightLocator_base: Context.TagClass<PlaywrightLocator, "effect-playwright/PlaywrightLocator", PlaywrightLocatorService>;
149
+ /**
150
+ * A service that provides a `PlaywrightLocator` instance.
151
+ *
152
+ * @since 0.1.0
153
+ * @category tag
154
+ */
155
+ declare class PlaywrightLocator extends PlaywrightLocator_base {
156
+ /**
157
+ * Creates a `PlaywrightLocator` from a Playwright `Locator` instance. This is mostly for internal use.
158
+ * But you could use this if you have used `use` or similar to wrap the locator.
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * const playwrightNativeLocator = yield* page.use((p) => p.locator("button"));
163
+ * const locator = PlaywrightLocator.make(playwrightNativeLocator);
164
+ * ```
165
+ *
166
+ * @param locator - The Playwright `Locator` instance to wrap.
167
+ * @since 0.1.0
168
+ * @category constructor
169
+ */
170
+ static make(locator: Locator): typeof PlaywrightLocator.Service;
171
+ }
172
+ //#endregion
173
+ //#region src/page.d.ts
174
+ interface PlaywrightPageEvents {
175
+ close: Page;
176
+ console: ConsoleMessage;
177
+ crash: Page;
178
+ dialog: Dialog;
179
+ domcontentloaded: Page;
180
+ download: Download;
181
+ filechooser: FileChooser;
182
+ frameattached: Frame;
183
+ framedetached: Frame;
184
+ framenavigated: Frame;
185
+ load: Page;
186
+ pageerror: Error;
187
+ popup: Page;
188
+ request: Request;
189
+ requestfailed: Request;
190
+ requestfinished: Request;
191
+ response: Response;
192
+ websocket: WebSocket;
193
+ worker: Worker;
194
+ }
195
+ interface PlaywrightPageService {
196
+ /**
197
+ * Navigates the page to the given URL.
198
+ *
199
+ * @example
200
+ * ```ts
201
+ * yield* page.goto("https://google.com");
202
+ * ```
203
+ *
204
+ * @see {@link Page.goto}
205
+ * @since 0.1.0
206
+ */
207
+ readonly goto: (url: string, options?: Parameters<Page["goto"]>[1]) => Effect.Effect<void, PlaywrightError>;
208
+ /**
209
+ * Waits for the page to navigate to the given URL.
210
+ *
211
+ * @example
212
+ * ```ts
213
+ * yield* page.waitForURL("https://google.com");
214
+ * ```
215
+ *
216
+ * @see {@link Page.waitForURL}
217
+ * @since 0.1.0
218
+ */
219
+ readonly waitForURL: (url: Parameters<Page["waitForURL"]>[0], options?: Parameters<Page["waitForURL"]>[1]) => Effect.Effect<void, PlaywrightError>;
220
+ /**
221
+ * Evaluates a function in the context of the page.
222
+ *
223
+ * @example
224
+ * ```ts
225
+ * const dimensions = yield* page.evaluate(() => ({
226
+ * width: document.documentElement.clientWidth,
227
+ * height: document.documentElement.clientHeight
228
+ * }));
229
+ * ```
230
+ *
231
+ * @see {@link Page.evaluate}
232
+ * @since 0.1.0
233
+ */
234
+ readonly evaluate: <R, Arg = void>(pageFunction: PageFunction<Arg, R>, arg?: Arg) => Effect.Effect<R, PlaywrightError>;
235
+ /**
236
+ * Returns the page title.
237
+ *
238
+ * @example
239
+ * ```ts
240
+ * const title = yield* page.title;
241
+ * ```
242
+ *
243
+ * @see {@link Page.title}
244
+ * @since 0.1.0
245
+ */
246
+ readonly title: Effect.Effect<string, PlaywrightError>;
247
+ /**
248
+ * A generic utility to execute any promise-based method on the underlying Playwright `Page`.
249
+ * Can be used to access any Page functionality not directly exposed by this service.
250
+ *
251
+ * @example
252
+ * ```ts
253
+ * const title = yield* page.use((p) => p.title());
254
+ * ```
255
+ *
256
+ * @see {@link Page}
257
+ * @since 0.1.0
258
+ */
259
+ readonly use: <T$1>(f: (page: Page) => Promise<T$1>) => Effect.Effect<T$1, PlaywrightError>;
260
+ /**
261
+ * Returns a locator for the given selector.
262
+ *
263
+ * @see {@link Page.locator}
264
+ * @since 0.1.0
265
+ */
266
+ readonly locator: (selector: string, options?: Parameters<Page["locator"]>[1]) => typeof PlaywrightLocator.Service;
267
+ /**
268
+ * Returns a locator that matches the given role.
269
+ *
270
+ * @see {@link Page.getByRole}
271
+ * @since 0.1.0
272
+ */
273
+ readonly getByRole: (role: Parameters<Page["getByRole"]>[0], options?: Parameters<Page["getByRole"]>[1]) => typeof PlaywrightLocator.Service;
274
+ /**
275
+ * Returns a locator that matches the given text.
276
+ *
277
+ * @see {@link Page.getByText}
278
+ * @since 0.1.0
279
+ */
280
+ readonly getByText: (text: Parameters<Page["getByText"]>[0], options?: Parameters<Page["getByText"]>[1]) => typeof PlaywrightLocator.Service;
281
+ /**
282
+ * Returns a locator that matches the given label.
283
+ *
284
+ * @see {@link Page.getByLabel}
285
+ * @since 0.1.0
286
+ */
287
+ readonly getByLabel: (label: Parameters<Page["getByLabel"]>[0], options?: Parameters<Page["getByLabel"]>[1]) => typeof PlaywrightLocator.Service;
288
+ /**
289
+ * Returns a locator that matches the given test id.
290
+ *
291
+ * @see {@link Page.getByTestId}
292
+ * @since 0.1.0
293
+ */
294
+ readonly getByTestId: (testId: Parameters<Page["getByTestId"]>[0]) => typeof PlaywrightLocator.Service;
295
+ /**
296
+ * Reloads the page.
297
+ *
298
+ * @see {@link Page.reload}
299
+ * @since 0.1.0
300
+ */
301
+ readonly reload: Effect.Effect<void, PlaywrightError>;
302
+ /**
303
+ * Closes the page.
304
+ *
305
+ * @see {@link Page.close}
306
+ * @since 0.1.0
307
+ */
308
+ readonly close: Effect.Effect<void, PlaywrightError>;
309
+ /**
310
+ * Returns the current URL of the page.
311
+ *
312
+ * @example
313
+ * ```ts
314
+ * const url = yield* page.url;
315
+ * ```
316
+ *
317
+ * @see {@link Page.url}
318
+ * @since 0.1.0
319
+ */
320
+ readonly url: Effect.Effect<string, PlaywrightError>;
321
+ /**
322
+ * Creates a stream of the given event from the page.
323
+ *
324
+ * @example
325
+ * ```ts
326
+ * const consoleStream = page.eventStream("console");
327
+ * ```
328
+ *
329
+ * @see {@link Page.on}
330
+ * @since 0.1.0
331
+ */
332
+ readonly eventStream: <K extends keyof PlaywrightPageEvents>(event: K) => Stream.Stream<PlaywrightPageEvents[K]>;
333
+ /**
334
+ * Clicks an element matching the given selector.
335
+ *
336
+ * @example
337
+ * ```ts
338
+ * yield* page.click("button#submit");
339
+ * ```
340
+ * @deprecated Use {@link PlaywrightPageService.locator} to create a locator and then call `click` on it instead.
341
+ * @see {@link Page.click}
342
+ * @since 0.1.0
343
+ * @category deprecated
344
+ */
345
+ readonly click: (selector: string, options?: Parameters<Page["click"]>[1]) => Effect.Effect<void, PlaywrightError>;
346
+ }
347
+ declare const PlaywrightPage_base: Context.TagClass<PlaywrightPage, "effect-playwright/PlaywrightPage", PlaywrightPageService>;
348
+ /**
349
+ * @category tag
350
+ */
351
+ declare class PlaywrightPage extends PlaywrightPage_base {
352
+ /**
353
+ * Creates a `PlaywrightPage` from a Playwright `Page` instance.
354
+ *
355
+ * @param page - The Playwright `Page` instance to wrap.
356
+ * @since 0.1.0
357
+ */
358
+ static make(page: Page): PlaywrightPageService;
359
+ }
360
+ //#endregion
361
+ //#region src/browser-context.d.ts
362
+ declare const PlaywrightBrowserContext_base: Context.TagClass<PlaywrightBrowserContext, "cehs/backend/lib/playwright/PlaywrightBrowserContext", {
363
+ readonly pages: Effect.Effect<Array<typeof PlaywrightPage.Service>>;
364
+ readonly newPage: Effect.Effect<typeof PlaywrightPage.Service, PlaywrightError>;
365
+ readonly close: Effect.Effect<void, PlaywrightError>;
366
+ }>;
367
+ declare class PlaywrightBrowserContext extends PlaywrightBrowserContext_base {
368
+ static make(context: BrowserContext): {
369
+ readonly pages: Effect.Effect<Array<typeof PlaywrightPage.Service>>;
370
+ readonly newPage: Effect.Effect<typeof PlaywrightPage.Service, PlaywrightError>;
371
+ readonly close: Effect.Effect<void, PlaywrightError>;
372
+ };
373
+ }
374
+ //#endregion
375
+ //#region src/browser.d.ts
376
+ type LaunchOptions$1 = Parameters<typeof chromium.launch>[0];
377
+ type NewPageOptions = Parameters<Browser["newPage"]>[0];
378
+ type NewContextOptions = Parameters<Browser["newContext"]>[0];
379
+ declare const PlaywrightBrowser_base: Context.TagClass<PlaywrightBrowser, "cehs/backend/lib/playwright/PlaywrightBrowser", {
380
+ /**
381
+ * Opens a new page in the browser.
382
+ *
383
+ * @example
384
+ * ```typescript
385
+ * const page = yield* browser.newPage();
386
+ * ```
387
+ *
388
+ * @param options - Optional options for creating the new page.
389
+ * @returns An effect that resolves to a `PlaywrightPage` service.
390
+ * @see {@link Browser.newPage}
391
+ */
392
+ readonly newPage: (options?: NewPageOptions) => Effect.Effect<typeof PlaywrightPage.Service, PlaywrightError>;
393
+ /**
394
+ * A generic utility to execute any promise-based method on the underlying Playwright `Browser`.
395
+ * Can be used to access any Browser functionality not directly exposed by this service.
396
+ *
397
+ * @example
398
+ * ```typescript
399
+ * const contexts = yield* browser.use((b) => b.contexts());
400
+ * ```
401
+ *
402
+ * @param f - A function that takes the Playwright `Browser` and returns a `Promise`.
403
+ * @returns An effect that wraps the promise and returns its result.
404
+ * @see {@link Browser}
405
+ */
406
+ readonly use: <T$1>(f: (browser: Browser) => Promise<T$1>) => Effect.Effect<T$1, PlaywrightError>;
407
+ /**
408
+ * An Effect that closes the browser and all of its pages.
409
+ * @see {@link Browser.close}
410
+ */
411
+ readonly close: Effect.Effect<void, PlaywrightError>;
412
+ /**
413
+ * An Effect that returns the list of all open browser contexts.
414
+ * @see {@link Browser.contexts}
415
+ */
416
+ readonly contexts: Effect.Effect<Array<typeof PlaywrightBrowserContext.Service>>;
417
+ readonly newContext: (options?: NewContextOptions) => Effect.Effect<typeof PlaywrightBrowserContext.Service, PlaywrightError, Scope$1>;
418
+ /**
419
+ * An Effect that returns the browser type (chromium, firefox or webkit) that the browser belongs to.
420
+ * @see {@link Browser.browserType}
421
+ */
422
+ readonly browserType: Effect.Effect<BrowserType>;
423
+ /**
424
+ * An Effect that returns the version of the browser.
425
+ * @see {@link Browser.version}
426
+ */
427
+ readonly version: Effect.Effect<string>;
428
+ /**
429
+ * An Effect that returns whether the browser is connected.
430
+ * @see {@link Browser.isConnected}
431
+ */
432
+ readonly isConnected: Effect.Effect<boolean>;
433
+ }>;
434
+ /**
435
+ * @category tag
436
+ */
437
+ declare class PlaywrightBrowser extends PlaywrightBrowser_base {
438
+ /**
439
+ * @category constructor
440
+ */
441
+ static make(browser: Browser): {
442
+ /**
443
+ * Opens a new page in the browser.
444
+ *
445
+ * @example
446
+ * ```typescript
447
+ * const page = yield* browser.newPage();
448
+ * ```
449
+ *
450
+ * @param options - Optional options for creating the new page.
451
+ * @returns An effect that resolves to a `PlaywrightPage` service.
452
+ * @see {@link Browser.newPage}
453
+ */
454
+ readonly newPage: (options?: NewPageOptions) => Effect.Effect<typeof PlaywrightPage.Service, PlaywrightError>;
455
+ /**
456
+ * A generic utility to execute any promise-based method on the underlying Playwright `Browser`.
457
+ * Can be used to access any Browser functionality not directly exposed by this service.
458
+ *
459
+ * @example
460
+ * ```typescript
461
+ * const contexts = yield* browser.use((b) => b.contexts());
462
+ * ```
463
+ *
464
+ * @param f - A function that takes the Playwright `Browser` and returns a `Promise`.
465
+ * @returns An effect that wraps the promise and returns its result.
466
+ * @see {@link Browser}
467
+ */
468
+ readonly use: <T$1>(f: (browser: Browser) => Promise<T$1>) => Effect.Effect<T$1, PlaywrightError>;
469
+ /**
470
+ * An Effect that closes the browser and all of its pages.
471
+ * @see {@link Browser.close}
472
+ */
473
+ readonly close: Effect.Effect<void, PlaywrightError>;
474
+ /**
475
+ * An Effect that returns the list of all open browser contexts.
476
+ * @see {@link Browser.contexts}
477
+ */
478
+ readonly contexts: Effect.Effect<Array<typeof PlaywrightBrowserContext.Service>>;
479
+ readonly newContext: (options?: NewContextOptions) => Effect.Effect<typeof PlaywrightBrowserContext.Service, PlaywrightError, Scope$1>;
480
+ /**
481
+ * An Effect that returns the browser type (chromium, firefox or webkit) that the browser belongs to.
482
+ * @see {@link Browser.browserType}
483
+ */
484
+ readonly browserType: Effect.Effect<BrowserType>;
485
+ /**
486
+ * An Effect that returns the version of the browser.
487
+ * @see {@link Browser.version}
488
+ */
489
+ readonly version: Effect.Effect<string>;
490
+ /**
491
+ * An Effect that returns whether the browser is connected.
492
+ * @see {@link Browser.isConnected}
493
+ */
494
+ readonly isConnected: Effect.Effect<boolean>;
495
+ };
496
+ }
497
+ //#endregion
498
+ //#region src/playwright.d.ts
499
+ interface PlaywrightService {
500
+ /**
501
+ * Launches a new browser instance.
502
+ *
503
+ * It is the caller's responsibility to manage the browser's lifecycle and close
504
+ * it when no longer needed. For automatic scope-based management, use
505
+ * {@link launchScoped} instead.
506
+ *
507
+ * ```ts
508
+ * import { Effect } from "effect";
509
+ * import { Playwright } from "effect-playwright";
510
+ * import { chromium } from "playwright-core";
511
+ *
512
+ * const program = Effect.gen(function* () {
513
+ * const browser = yield* Playwright.launch(chromium);
514
+ * // ... use browser ...
515
+ * yield* browser.close;
516
+ * });
517
+ *
518
+ * await Effect.runPromise(program);
519
+ * ```
520
+ *
521
+ * @param browserType - The browser type to launch (e.g. chromium, firefox, webkit).
522
+ * @param options - Optional launch options.
523
+ * @since 0.1.0
524
+ */
525
+ launch: (browserType: BrowserType, options?: LaunchOptions$1) => Effect.Effect<typeof PlaywrightBrowser.Service, PlaywrightError>;
526
+ /**
527
+ * Launches a new browser instance managed by a Scope.
528
+ *
529
+ * This method automatically closes the browser when the scope is closed.
530
+ *
531
+ * ```ts
532
+ * import { Effect } from "effect";
533
+ * import { Playwright } from "effect-playwright";
534
+ * import { chromium } from "playwright-core";
535
+ *
536
+ * const program = Effect.gen(function* () {
537
+ * const browser = yield* Playwright.launchScoped(chromium);
538
+ * // Browser will be closed automatically when scope closes
539
+ * });
540
+ *
541
+ * await Effect.runPromise(program);
542
+ * ```
543
+ *
544
+ * @param browserType - The browser type to launch (e.g. chromium, firefox, webkit).
545
+ * @param options - Optional launch options.
546
+ * @since 0.1.0
547
+ */
548
+ launchScoped: (browserType: BrowserType, options?: LaunchOptions$1) => Effect.Effect<typeof PlaywrightBrowser.Service, PlaywrightError, Scope.Scope>;
549
+ /**
550
+ * Connects to a browser instance via Chrome DevTools Protocol (CDP).
551
+ *
552
+ * Unlike {@link launchScoped}, this method does **not** close the browser when the
553
+ * scope is closed. It is the caller's responsibility to manage the browser's
554
+ * lifecycle.
555
+ *
556
+ * If you want to close the browser using a scope simply add a finalizer:
557
+ *
558
+ * ```ts
559
+ * import { Effect } from "effect";
560
+ * import { Playwright } from "effect-playwright";
561
+ *
562
+ * const program = Effect.gen(function* () {
563
+ * const browser = yield* Playwright.connectCDP(cdpUrl);
564
+ * yield* Effect.addFinalizer(() => browser.close.pipe(Effect.ignore));
565
+ * });
566
+ *
567
+ * await Effect.runPromise(program);
568
+ * ```
569
+ *
570
+ * @param cdpUrl - The CDP URL to connect to.
571
+ * @param options - Optional options for connecting to the CDP URL.
572
+ * @since 0.1.0
573
+ */
574
+ connectCDP: (cdpUrl: string, options?: ConnectOverCDPOptions) => Effect.Effect<typeof PlaywrightBrowser.Service, PlaywrightError>;
575
+ }
576
+ declare const Playwright_base: Context.TagClass<Playwright, "effect-playwright/index/Playwright", PlaywrightService>;
577
+ declare class Playwright extends Playwright_base {
578
+ /**
579
+ * @category layer
580
+ */
581
+ static readonly layer: Layer.Layer<Playwright, never, never>;
582
+ }
583
+ //#endregion
584
+ export { NewPageOptions as a, PlaywrightPageService as c, PlaywrightError as d, NewContextOptions as i, PlaywrightLocator as l, PlaywrightService as n, PlaywrightBrowser as o, LaunchOptions$1 as r, PlaywrightPage as s, Playwright as t, PlaywrightLocatorService as u };
@@ -0,0 +1,2 @@
1
+ import { a as NewPageOptions, c as PlaywrightPageService, i as NewContextOptions, l as PlaywrightLocator, n as PlaywrightService, o as PlaywrightBrowser, r as LaunchOptions, s as PlaywrightPage, t as Playwright, u as PlaywrightLocatorService } from "./index-aR0Fa_4Y.mjs";
2
+ export { LaunchOptions, NewContextOptions, NewPageOptions, Playwright, PlaywrightBrowser, PlaywrightLocator, PlaywrightLocatorService, PlaywrightPage, PlaywrightPageService, PlaywrightService };
package/dist/index.mjs ADDED
@@ -0,0 +1,3 @@
1
+ import { i as PlaywrightLocator, n as PlaywrightBrowser, r as PlaywrightPage, t as Playwright } from "./src-DveiwW4g.mjs";
2
+
3
+ export { Playwright, PlaywrightBrowser, PlaywrightLocator, PlaywrightPage };
@@ -0,0 +1,167 @@
1
+ import { Context, Data, Effect, Layer, Stream } from "effect";
2
+ import { chromium, errors } from "playwright-core";
3
+
4
+ //#region src/errors.ts
5
+ var PlaywrightError = class extends Data.TaggedError("PlaywrightError") {};
6
+ function wrapError(error) {
7
+ if (error instanceof errors.TimeoutError) return new PlaywrightError({
8
+ reason: "Timeout",
9
+ cause: error
10
+ });
11
+ else return new PlaywrightError({
12
+ reason: "Unknown",
13
+ cause: error
14
+ });
15
+ }
16
+
17
+ //#endregion
18
+ //#region src/utils.ts
19
+ /** @internal */
20
+ const useHelper = (api) => (userFunction) => Effect.tryPromise(() => userFunction(api)).pipe(Effect.mapError(wrapError));
21
+
22
+ //#endregion
23
+ //#region src/locator.ts
24
+ /**
25
+ * A service that provides a `PlaywrightLocator` instance.
26
+ *
27
+ * @since 0.1.0
28
+ * @category tag
29
+ */
30
+ var PlaywrightLocator = class PlaywrightLocator extends Context.Tag("effect-playwright/PlaywrightLocator")() {
31
+ /**
32
+ * Creates a `PlaywrightLocator` from a Playwright `Locator` instance. This is mostly for internal use.
33
+ * But you could use this if you have used `use` or similar to wrap the locator.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * const playwrightNativeLocator = yield* page.use((p) => p.locator("button"));
38
+ * const locator = PlaywrightLocator.make(playwrightNativeLocator);
39
+ * ```
40
+ *
41
+ * @param locator - The Playwright `Locator` instance to wrap.
42
+ * @since 0.1.0
43
+ * @category constructor
44
+ */
45
+ static make(locator) {
46
+ const use = useHelper(locator);
47
+ return PlaywrightLocator.of({
48
+ click: (options) => use((l) => l.click(options)),
49
+ fill: (value, options) => use((l) => l.fill(value, options)),
50
+ getAttribute: (name, options) => use((l) => l.getAttribute(name, options)),
51
+ innerText: (options) => use((l) => l.innerText(options)),
52
+ innerHTML: (options) => use((l) => l.innerHTML(options)),
53
+ inputValue: (options) => use((l) => l.inputValue(options)),
54
+ textContent: (options) => use((l) => l.textContent(options)),
55
+ count: use((l) => l.count()),
56
+ first: () => PlaywrightLocator.make(locator.first()),
57
+ last: () => PlaywrightLocator.make(locator.last()),
58
+ nth: (index) => PlaywrightLocator.make(locator.nth(index)),
59
+ evaluate: (pageFunction, arg, options) => use((l) => l.evaluate(pageFunction, arg, options)),
60
+ use
61
+ });
62
+ }
63
+ };
64
+
65
+ //#endregion
66
+ //#region src/page.ts
67
+ /**
68
+ * @category tag
69
+ */
70
+ var PlaywrightPage = class PlaywrightPage extends Context.Tag("effect-playwright/PlaywrightPage")() {
71
+ /**
72
+ * Creates a `PlaywrightPage` from a Playwright `Page` instance.
73
+ *
74
+ * @param page - The Playwright `Page` instance to wrap.
75
+ * @since 0.1.0
76
+ */
77
+ static make(page) {
78
+ const use = useHelper(page);
79
+ return PlaywrightPage.of({
80
+ goto: (url, options) => use((p) => p.goto(url, options)),
81
+ waitForURL: (url, options) => use((p) => p.waitForURL(url, options)),
82
+ title: use((p) => p.title()),
83
+ evaluate: (f, arg) => use((p) => p.evaluate(f, arg)),
84
+ locator: (selector, options) => PlaywrightLocator.make(page.locator(selector, options)),
85
+ getByRole: (role, options) => PlaywrightLocator.make(page.getByRole(role, options)),
86
+ getByText: (text, options) => PlaywrightLocator.make(page.getByText(text, options)),
87
+ getByLabel: (label, options) => PlaywrightLocator.make(page.getByLabel(label, options)),
88
+ getByTestId: (testId) => PlaywrightLocator.make(page.getByTestId(testId)),
89
+ url: Effect.sync(() => page.url()),
90
+ reload: use((p) => p.reload()),
91
+ close: use((p) => p.close()),
92
+ click: (selector, options) => use((p) => p.click(selector, options)),
93
+ eventStream: (event) => Stream.asyncPush((emit) => Effect.acquireRelease(Effect.sync(() => page.on(event, emit.single)), () => Effect.sync(() => page.off(event, emit.single)))),
94
+ use
95
+ });
96
+ }
97
+ };
98
+
99
+ //#endregion
100
+ //#region src/browser-context.ts
101
+ var PlaywrightBrowserContext = class PlaywrightBrowserContext extends Context.Tag("cehs/backend/lib/playwright/PlaywrightBrowserContext")() {
102
+ static make(context) {
103
+ const use = useHelper(context);
104
+ return PlaywrightBrowserContext.of({
105
+ pages: Effect.sync(() => context.pages().map(PlaywrightPage.make)),
106
+ newPage: use((c) => c.newPage().then(PlaywrightPage.make)),
107
+ close: use((c) => c.close())
108
+ });
109
+ }
110
+ };
111
+
112
+ //#endregion
113
+ //#region src/browser.ts
114
+ /**
115
+ * @category tag
116
+ */
117
+ var PlaywrightBrowser = class PlaywrightBrowser extends Context.Tag("cehs/backend/lib/playwright/PlaywrightBrowser")() {
118
+ /**
119
+ * @category constructor
120
+ */
121
+ static make(browser) {
122
+ const use = useHelper(browser);
123
+ return PlaywrightBrowser.of({
124
+ newPage: (options) => use((browser$1) => browser$1.newPage(options).then(PlaywrightPage.make)),
125
+ close: use((browser$1) => browser$1.close()),
126
+ contexts: Effect.sync(() => browser.contexts().map(PlaywrightBrowserContext.make)),
127
+ newContext: (options) => Effect.acquireRelease(use((browser$1) => browser$1.newContext(options).then(PlaywrightBrowserContext.make)), (context) => context.close.pipe(Effect.ignoreLogged)),
128
+ browserType: Effect.sync(() => browser.browserType()),
129
+ version: Effect.sync(() => browser.version()),
130
+ isConnected: Effect.sync(() => browser.isConnected()),
131
+ use
132
+ });
133
+ }
134
+ };
135
+
136
+ //#endregion
137
+ //#region src/playwright.ts
138
+ const launch = Effect.fn(function* (browserType, options) {
139
+ const rawBrowser = yield* Effect.tryPromise({
140
+ try: () => browserType.launch(options),
141
+ catch: wrapError
142
+ });
143
+ return PlaywrightBrowser.make(rawBrowser);
144
+ });
145
+ var Playwright = class Playwright extends Context.Tag("effect-playwright/index/Playwright")() {
146
+ /**
147
+ * @category layer
148
+ */
149
+ static layer = Layer.succeed(Playwright, {
150
+ launch,
151
+ launchScoped: Effect.fn(function* (browserType, options) {
152
+ const browser = yield* launch(browserType, options);
153
+ yield* Effect.addFinalizer(() => browser.close.pipe(Effect.ignore));
154
+ return browser;
155
+ }),
156
+ connectCDP: Effect.fn(function* (cdpUrl, options) {
157
+ const browser = yield* Effect.tryPromise({
158
+ try: () => chromium.connectOverCDP(cdpUrl, options),
159
+ catch: wrapError
160
+ });
161
+ return PlaywrightBrowser.make(browser);
162
+ })
163
+ });
164
+ };
165
+
166
+ //#endregion
167
+ export { PlaywrightLocator as i, PlaywrightBrowser as n, PlaywrightPage as r, Playwright as t };
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "effect-playwright",
3
+ "type": "module",
4
+ "version": "0.1.0",
5
+ "description": "An Effect-based Playwright library.",
6
+ "author": "Jobflow GmbH",
7
+ "license": "ISC",
8
+ "homepage": "https://github.com/Jobflow-io/effect-playwright",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/Jobflow-io/effect-playwright.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/Jobflow-io/effect-playwright/issues"
15
+ },
16
+ "exports": {
17
+ ".": "./dist/index.mjs",
18
+ "./experimental": "./dist/experimental/index.mjs",
19
+ "./package.json": "./package.json"
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "keywords": [
25
+ "effect",
26
+ "effect-ts",
27
+ "playwright",
28
+ "browser",
29
+ "automation"
30
+ ],
31
+ "dependencies": {
32
+ "playwright-core": "^1.57.0"
33
+ },
34
+ "peerDependencies": {
35
+ "@effect/platform": "^0.93.3",
36
+ "effect": "^3.19.6"
37
+ },
38
+ "devDependencies": {
39
+ "@biomejs/biome": "2.3.11",
40
+ "@effect/language-service": "^0.64.1",
41
+ "@effect/platform": "^0.94.1",
42
+ "@effect/platform-node": "^0.104.0",
43
+ "@effect/vitest": "^0.27.0",
44
+ "effect": "^3.19.14",
45
+ "playwright": "^1.57.0",
46
+ "tsdown": "^0.19.0",
47
+ "tsx": "^4.21.0",
48
+ "typescript": "^5.9.3",
49
+ "vitest": "^4.0.16"
50
+ },
51
+ "types": "./dist/index.d.mts",
52
+ "scripts": {
53
+ "build": "tsdown",
54
+ "test": "vitest run",
55
+ "type-check": "tsc --noEmit"
56
+ }
57
+ }