effect-playwright 0.1.0 → 0.1.2

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
@@ -1,10 +1,15 @@
1
1
  # effect-playwright
2
2
 
3
+ [![NPM Version](https://img.shields.io/npm/v/effect-playwright)](https://www.npmjs.com/package/effect-playwright)
3
4
  [![GitHub License](https://img.shields.io/github/license/Jobflow-io/effect-playwright)](https://github.com/Jobflow-io/effect-playwright/blob/main/LICENSE)
4
5
  [![Effect: yes](https://img.shields.io/badge/effect-yes-blue)](https://effect.website/)
6
+ [![Documentation](https://img.shields.io/badge/view_documentation-purple)](https://jobflow-io.github.io/effect-playwright/modules/index.html)
5
7
 
6
8
  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
9
 
10
+ > [!NOTE]
11
+ > This library is currently focused on using Playwright for **automation** and **scraping**. It does not provide a wrapper for `@playwright/test` (the test runner).
12
+
8
13
  ## Installation
9
14
 
10
15
  ```bash
@@ -17,6 +22,8 @@ or
17
22
  npm install effect-playwright playwright-core
18
23
  ```
19
24
 
25
+ You can also install `playwright` instead of `playwright-core` if you want the post-build auto install of the browsers.
26
+
20
27
  ## Quick Start
21
28
 
22
29
  ```ts
@@ -49,6 +56,36 @@ const program = Effect.gen(function* () {
49
56
  }).pipe(Effect.scoped);
50
57
  ```
51
58
 
59
+ ## Connecting via CDP
60
+
61
+ You can connect to an existing browser instance using the Chrome DevTools Protocol (CDP).
62
+
63
+ ```ts
64
+ const program = Effect.gen(function* () {
65
+ const playwright = yield* Playwright;
66
+
67
+ // Use connectCDPScoped to automatically close the CONNECTION when the scope ends
68
+ // Note: This does NOT close the browser process itself, only the CDP connection.
69
+ const browser = yield* playwright.connectCDPScoped("http://localhost:9222");
70
+
71
+ const page = yield* browser.newPage();
72
+ // ...
73
+ }).pipe(Effect.scoped);
74
+ ```
75
+
76
+ If you need to manage the connection lifecycle manually, use `connectCDP`:
77
+
78
+ ```ts
79
+ const program = Effect.gen(function* () {
80
+ const playwright = yield* Playwright;
81
+ const browser = yield* playwright.connectCDP("http://localhost:9222");
82
+
83
+ // ... use browser ...
84
+
85
+ yield* browser.close;
86
+ });
87
+ ```
88
+
52
89
  ## PlaywrightEnvironment (Experimental)
53
90
 
54
91
  The `PlaywrightEnvironment` simplifies setup by allowing you to configure the browser type and launch options once and reuse them across your application.
@@ -75,6 +112,55 @@ const program = Effect.gen(function* () {
75
112
  await Effect.runPromise(program.pipe(Effect.provide(liveLayer)));
76
113
  ```
77
114
 
115
+ ### `PlaywrightEnvironment.withBrowser`
116
+
117
+ The `withBrowser` utility provides the `PlaywrightBrowser` service to your effect. It internally manages a `Scope`, which means the browser will be launched when the effect starts and closed automatically when the effect finishes (including on failure or interruption).
118
+
119
+ ```ts
120
+ const program = Effect.gen(function* () {
121
+ const browser = yield* PlaywrightBrowser; // Now available in context
122
+ const page = yield* browser.newPage();
123
+
124
+ // ...
125
+ // Browser close is ensured
126
+ }).pipe(PlaywrightEnvironment.withBrowser);
127
+ ```
128
+
129
+ ## Event Handling
130
+
131
+ You can listen to Playwright events using the `eventStream` method. This returns an Effect `Stream` that emits events as they occur.
132
+
133
+ > [!NOTE]
134
+ > `eventStream` emits "Effectified" wrappers (e.g., `PlaywrightRequest`, `PlaywrightResponse`, `PlaywrightPage`) for most events. This allows you to continue using the Effect ecosystem seamlessly within your event handlers.
135
+
136
+ The stream is automatically managed and will close when the underlying resource (like the Page or Browser) is closed.
137
+
138
+ ### Example: Monitoring Network Requests
139
+
140
+ Since event streams run indefinitely until the resource closes, you often need to **fork** the resulting effect so it runs in the background without blocking your main program flow.
141
+
142
+ ```ts
143
+ const program = Effect.gen(function* () {
144
+ const browser = yield* PlaywrightBrowser;
145
+ const page = yield* browser.newPage();
146
+
147
+ // Create a stream of request events
148
+ yield* page.eventStream("request").pipe(
149
+ Stream.runForEach((request) =>
150
+ Effect.gen(function* () {
151
+ const url = yield* request.url;
152
+ yield* Effect.log(`Request: ${url}`);
153
+ }),
154
+ ),
155
+
156
+ // Fork to run it in the background
157
+ Effect.fork,
158
+ );
159
+
160
+ yield* page.goto("https://example.com");
161
+ }).pipe(PlaywrightEnvironment.withBrowser);
162
+ ```
163
+
78
164
  ## Accessing Native Playwright
79
165
 
80
166
  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).
@@ -1,4 +1,4 @@
1
- import { d as PlaywrightError, o as PlaywrightBrowser } from "../index-aR0Fa_4Y.mjs";
1
+ import { o as PlaywrightBrowser, x as PlaywrightError } from "../index-BTxElyN5.mjs";
2
2
  import { Context, Effect, Layer } from "effect";
3
3
  import { BrowserType, LaunchOptions } from "playwright-core";
4
4
  import { Scope as Scope$1 } from "effect/Scope";
@@ -13,9 +13,9 @@ declare const PlaywrightEnvironment_base: Context.TagClass<PlaywrightEnvironment
13
13
  /**
14
14
  * Most of the time you want to use the same kind of browser and configuration every time you use Playwright.
15
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.
16
+ * use `PlaywrightEnvironment.browser` to start browsers scoped to the current lifetime. They will be closed when the scope is closed.
17
17
  *
18
- * You can use {@link PlaywrightEnvironment.withBrowser} to provide the `PlaywrightBrowser` service to the wrapped effect. This
18
+ * You can use {@link withBrowser} to provide the `PlaywrightBrowser` service to the wrapped effect. This
19
19
  * also allows you to re-use the same browser as many times as you want.
20
20
  *
21
21
  * @since 0.1.0
@@ -35,10 +35,11 @@ declare class PlaywrightEnvironment extends PlaywrightEnvironment_base {}
35
35
  *
36
36
  * // use the layer
37
37
  * const program = Effect.gen(function* () {
38
- * const browser = yield* PlaywrightEnvironment.browser;
38
+ * const playwright = yield* PlaywrightEnvironment;
39
+ * const browser = yield* playwright.browser;
39
40
  * const page = yield* browser.newPage();
40
41
  * yield* page.goto("https://example.com");
41
- * }).pipe(PlaywrightEnvironment.withBrowser, Effect.provide(playwrightEnv));
42
+ * }).pipe(Effect.scoped, Effect.provide(playwrightEnv));
42
43
  * ```
43
44
  *
44
45
  * @param browser - The Playwright BrowserType implementation (e.g. `chromium`, `firefox`, `webkit`).
@@ -59,15 +60,17 @@ declare const layer: (browser: BrowserType, launchOptions?: LaunchOptions) => La
59
60
  * import { PlaywrightEnvironment } from "effect-playwright/experimental";
60
61
  * import { chromium } from "playwright-core";
61
62
  *
62
- * const layer = PlaywrightEnvironment.layer(chromium);
63
+ * const env = PlaywrightEnvironment.layer(chromium);
64
+ *
63
65
  * const program = Effect.gen(function* () {
64
66
  * const browser = yield* PlaywrightBrowser;
65
67
  * const page = yield* browser.newPage();
66
68
  * yield* page.goto("https://example.com");
67
- * }).pipe(PlaywrightEnvironment.withBrowser);
69
+ * }).pipe(PlaywrightEnvironment.withBrowser, Effect.provide(env));
68
70
  * ```
69
71
  *
70
72
  * @since 0.1.0
73
+ * @category util
71
74
  */
72
75
  declare const withBrowser: <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, PlaywrightError | E, PlaywrightEnvironment | Exclude<R, PlaywrightBrowser>>;
73
76
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "../chunk-BiucMVzj.mjs";
2
- import { n as PlaywrightBrowser, t as Playwright } from "../src-DveiwW4g.mjs";
2
+ import { n as PlaywrightBrowser, t as Playwright } from "../src-D0uXY5ik.mjs";
3
3
  import { Context, Effect, Layer } from "effect";
4
4
 
5
5
  //#region src/experimental/environment.ts
@@ -11,9 +11,9 @@ var environment_exports = /* @__PURE__ */ __exportAll({
11
11
  /**
12
12
  * Most of the time you want to use the same kind of browser and configuration every time you use Playwright.
13
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.
14
+ * use `PlaywrightEnvironment.browser` to start browsers scoped to the current lifetime. They will be closed when the scope is closed.
15
15
  *
16
- * You can use {@link PlaywrightEnvironment.withBrowser} to provide the `PlaywrightBrowser` service to the wrapped effect. This
16
+ * You can use {@link withBrowser} to provide the `PlaywrightBrowser` service to the wrapped effect. This
17
17
  * also allows you to re-use the same browser as many times as you want.
18
18
  *
19
19
  * @since 0.1.0
@@ -33,10 +33,11 @@ var PlaywrightEnvironment = class extends Context.Tag("effect-playwright/experim
33
33
  *
34
34
  * // use the layer
35
35
  * const program = Effect.gen(function* () {
36
- * const browser = yield* PlaywrightEnvironment.browser;
36
+ * const playwright = yield* PlaywrightEnvironment;
37
+ * const browser = yield* playwright.browser;
37
38
  * const page = yield* browser.newPage();
38
39
  * yield* page.goto("https://example.com");
39
- * }).pipe(PlaywrightEnvironment.withBrowser, Effect.provide(playwrightEnv));
40
+ * }).pipe(Effect.scoped, Effect.provide(playwrightEnv));
40
41
  * ```
41
42
  *
42
43
  * @param browser - The Playwright BrowserType implementation (e.g. `chromium`, `firefox`, `webkit`).
@@ -61,15 +62,17 @@ const layer = (browser, launchOptions) => {
61
62
  * import { PlaywrightEnvironment } from "effect-playwright/experimental";
62
63
  * import { chromium } from "playwright-core";
63
64
  *
64
- * const layer = PlaywrightEnvironment.layer(chromium);
65
+ * const env = PlaywrightEnvironment.layer(chromium);
66
+ *
65
67
  * const program = Effect.gen(function* () {
66
68
  * const browser = yield* PlaywrightBrowser;
67
69
  * const page = yield* browser.newPage();
68
70
  * yield* page.goto("https://example.com");
69
- * }).pipe(PlaywrightEnvironment.withBrowser);
71
+ * }).pipe(PlaywrightEnvironment.withBrowser, Effect.provide(env));
70
72
  * ```
71
73
  *
72
74
  * @since 0.1.0
75
+ * @category util
73
76
  */
74
77
  const withBrowser = Effect.provide(PlaywrightEnvironment.pipe(Effect.map((e) => e.browser), Effect.flatten, Layer.scoped(PlaywrightBrowser)));
75
78