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 +86 -0
- package/dist/experimental/index.d.mts +10 -7
- package/dist/experimental/index.mjs +10 -7
- package/dist/index-BTxElyN5.d.mts +857 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/src-D0uXY5ik.mjs +389 -0
- package/package.json +9 -5
- package/dist/index-aR0Fa_4Y.d.mts +0 -584
- package/dist/src-DveiwW4g.mjs +0 -167
package/README.md
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
# effect-playwright
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/effect-playwright)
|
|
3
4
|
[](https://github.com/Jobflow-io/effect-playwright/blob/main/LICENSE)
|
|
4
5
|
[](https://effect.website/)
|
|
6
|
+
[](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 {
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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
|
|