Skip to content

Commit a2b0ec5

Browse files
authored
Merge pull request #1 from Jobflow-io/common-models
2 parents 198d45b + 1171592 commit a2b0ec5

File tree

9 files changed

+576
-62
lines changed

9 files changed

+576
-62
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ src/scratchpad.ts
33
dist
44
docs
55
context
6+
tmp
67

78
## in scratchpad, we only track setup.ts
89
src/scratchpad/*

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"@effect/platform": "^0.94.1",
4949
"@effect/platform-node": "^0.104.0",
5050
"@effect/vitest": "^0.27.0",
51+
"@types/node": "^25.0.8",
5152
"effect": "^3.19.14",
5253
"playwright": "^1.57.0",
5354
"tsdown": "0.20.0-beta.1",

pnpm-lock.yaml

Lines changed: 19 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/common.test.ts

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import { assert, layer } from "@effect/vitest";
2+
import { Effect, Fiber, Option, Stream } from "effect";
3+
import { chromium } from "playwright-core";
4+
import { PlaywrightBrowser } from "./browser";
5+
import { PlaywrightEnvironment } from "./experimental";
6+
7+
layer(PlaywrightEnvironment.layer(chromium))("PlaywrightCommon", (it) => {
8+
it.scoped("PlaywrightRequest and PlaywrightResponse", () =>
9+
Effect.gen(function* () {
10+
const browser = yield* PlaywrightBrowser;
11+
const page = yield* browser.newPage();
12+
13+
const requestFiber = yield* page
14+
.eventStream("request")
15+
.pipe(Stream.runHead)
16+
.pipe(Effect.fork);
17+
18+
const responseFiber = yield* page
19+
.eventStream("response")
20+
.pipe(Stream.runHead)
21+
.pipe(Effect.fork);
22+
23+
yield* page.goto("http://example.com");
24+
25+
const request = yield* Fiber.join(requestFiber).pipe(Effect.flatten);
26+
const response = yield* Fiber.join(responseFiber).pipe(Effect.flatten);
27+
28+
assert((yield* request.url).includes("example.com"));
29+
assert((yield* request.method) === "GET");
30+
assert((yield* request.isNavigationRequest) === true);
31+
32+
assert((yield* response.url).includes("example.com"));
33+
assert((yield* response.ok) === true);
34+
assert((yield* response.status) === 200);
35+
36+
const headers = yield* response.headers;
37+
assert(headers["content-type"] !== undefined);
38+
39+
const respRequest = response.request();
40+
assert((yield* respRequest.url).includes("example.com"));
41+
42+
const requestResponse = yield* request.response;
43+
assert(Option.isSome(requestResponse));
44+
assert((yield* requestResponse.value.url) === (yield* response.url));
45+
}).pipe(PlaywrightEnvironment.withBrowser),
46+
);
47+
48+
it.scoped("PlaywrightWorker", () =>
49+
Effect.gen(function* () {
50+
const browser = yield* PlaywrightBrowser;
51+
const page = yield* browser.newPage();
52+
53+
const workerFiber = yield* page
54+
.eventStream("worker")
55+
.pipe(Stream.runHead)
56+
.pipe(Effect.fork);
57+
58+
yield* page.evaluate(() => {
59+
const blob = new Blob(['console.log("worker")'], {
60+
type: "application/javascript",
61+
});
62+
new Worker(URL.createObjectURL(blob));
63+
});
64+
65+
const worker = yield* Fiber.join(workerFiber).pipe(Effect.flatten);
66+
67+
assert((yield* worker.url).startsWith("blob:"));
68+
const result = yield* worker.evaluate(() => 1 + 1);
69+
assert(result === 2);
70+
}).pipe(PlaywrightEnvironment.withBrowser),
71+
);
72+
73+
it.scoped("PlaywrightDialog", () =>
74+
Effect.gen(function* () {
75+
const browser = yield* PlaywrightBrowser;
76+
const page = yield* browser.newPage();
77+
78+
const dialogFiber = yield* page
79+
.eventStream("dialog")
80+
.pipe(Stream.runHead)
81+
.pipe(Effect.fork);
82+
83+
yield* page.evaluate(() => {
84+
setTimeout(() => alert("hello world"), 10);
85+
});
86+
87+
const dialog = yield* Fiber.join(dialogFiber).pipe(Effect.flatten);
88+
89+
assert((yield* dialog.message) === "hello world");
90+
assert((yield* dialog.type) === "alert");
91+
92+
yield* dialog.accept();
93+
}).pipe(PlaywrightEnvironment.withBrowser),
94+
);
95+
96+
it.scoped("PlaywrightFileChooser", () =>
97+
Effect.gen(function* () {
98+
const browser = yield* PlaywrightBrowser;
99+
const page = yield* browser.newPage();
100+
101+
yield* page.evaluate(() => {
102+
document.body.innerHTML = '<input type="file" id="fileinput" />';
103+
});
104+
105+
const fileChooserFiber = yield* page
106+
.eventStream("filechooser")
107+
.pipe(Stream.runHead)
108+
.pipe(Effect.fork);
109+
110+
yield* page.locator("#fileinput").click();
111+
112+
const fileChooser = yield* Fiber.join(fileChooserFiber).pipe(
113+
Effect.flatten,
114+
);
115+
116+
assert((yield* fileChooser.isMultiple) === false);
117+
assert(fileChooser.element() !== null);
118+
}).pipe(PlaywrightEnvironment.withBrowser),
119+
);
120+
121+
it.scoped("PlaywrightDownload", () =>
122+
Effect.gen(function* () {
123+
const browser = yield* PlaywrightBrowser;
124+
const page = yield* browser.newPage();
125+
126+
yield* page.evaluate(() => {
127+
document.body.innerHTML =
128+
'<a text="Download" id="download" href="data:application/octet-stream,hello world" download="test.txt">Download</a>';
129+
});
130+
131+
const downloadFiber = yield* page
132+
.eventStream("download")
133+
.pipe(Stream.runHead)
134+
.pipe(Effect.fork);
135+
136+
yield* page.locator("#download").click();
137+
138+
const download = yield* Fiber.join(downloadFiber).pipe(Effect.flatten);
139+
140+
assert((yield* download.suggestedFilename) === "test.txt");
141+
const url = yield* download.url;
142+
assert(url.startsWith("data:"));
143+
}).pipe(PlaywrightEnvironment.withBrowser),
144+
);
145+
});

0 commit comments

Comments
 (0)