fluxwright 0.2.1 → 0.2.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/MISSING.md +19 -12
- package/README.md +19 -9
- package/addon.d.ts +13 -1
- package/addon.js +37 -0
- package/package.json +18 -10
package/MISSING.md
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
# Playwright
|
|
1
|
+
# Playwright features not in Fluxwright
|
|
2
2
|
|
|
3
|
-
The
|
|
3
|
+
The Node binding covers the same page API as the Rust crate. Some Playwright features are planned, and some are out of scope.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
- `
|
|
5
|
+
## Planned (see [ROADMAP.md](https://github.com/harshit-d3v/fluxwright/blob/main/ROADMAP.md))
|
|
6
|
+
|
|
7
|
+
- Saved login state: `storageState` import and export
|
|
8
|
+
- `page.route` to fulfill or modify requests (today: blocking by resource type or URL)
|
|
9
|
+
- Emulation: user agent, locale, timezone, geolocation, permissions, `emulateMedia`
|
|
10
|
+
- `locator.screenshot()`
|
|
11
|
+
- `getByLabel`, `getByPlaceholder`, `getByTestId`, `nth`, `filter`
|
|
12
|
+
- Downloads
|
|
13
|
+
- `connectOverCDP`, to use browsers you already run
|
|
14
|
+
- Python bindings
|
|
15
|
+
|
|
16
|
+
## Out of scope
|
|
17
|
+
|
|
18
|
+
- Firefox and WebKit
|
|
19
|
+
- Playwright Test: the runner, fixtures and `expect`
|
|
20
|
+
- Tracing, the trace viewer, codegen and video recording
|
|
12
21
|
- Multiple pages per context
|
|
13
|
-
-
|
|
14
|
-
- WebSocket / worker APIs
|
|
15
|
-
- `connectOverCDP` (planned as a later `BrowserSource`)
|
|
22
|
+
- WebSocket and worker APIs
|
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# fluxwright
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Run hundreds of headless Chrome jobs on one machine, with a Playwright-style API. Each `newPage` is a fresh browser context on a pooled Chrome. The engine queues jobs when every slot is busy, restarts browsers before they bloat, and replaces browsers that crash.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Docs: https://fluxwright.vercel.app
|
|
6
|
+
|
|
7
|
+
Requires a local Chrome/Chromium binary (`FLUXWRIGHT_CHROMIUM`, `CHROME`, `CHROMIUM`, or a standard install path). For headless jobs, chrome-headless-shell is picked up from `PATH` or Puppeteer's/Playwright's cache and opens pages much faster: `npx @puppeteer/browsers install chrome-headless-shell@stable`.
|
|
6
8
|
|
|
7
9
|
## Install
|
|
8
10
|
|
|
@@ -24,11 +26,9 @@ import { chromium } from "fluxwright";
|
|
|
24
26
|
const browser = await chromium.launch({ maxBrowsers: 4 });
|
|
25
27
|
const page = await browser.newPage();
|
|
26
28
|
await page.goto("https://example.com");
|
|
27
|
-
console.log(await page.
|
|
28
|
-
await page.
|
|
29
|
-
await page.
|
|
30
|
-
const html = await page.content();
|
|
31
|
-
const png = await page.screenshot(); // Buffer
|
|
29
|
+
console.log(await page.getByRole("heading").textContent()); // "Example Domain"
|
|
30
|
+
console.log(await page.evaluate(() => location.hostname));
|
|
31
|
+
const png = await page.screenshot({ fullPage: true }); // Buffer
|
|
32
32
|
await page.close();
|
|
33
33
|
await browser.close();
|
|
34
34
|
```
|
|
@@ -46,13 +46,23 @@ await browser.close();
|
|
|
46
46
|
| `page.click(selector)` / `page.fill(selector, value)` | Scrolls into view, waits until enabled, stable, and not covered. Selector: CSS, `text=Foo`, `text="Exact"`, `role=button[name="Save"]` |
|
|
47
47
|
| `page.getByRole(role, { name?, exact? })` / `page.getByText(text, { exact? })` / `page.locator(selector)` | `Locator` with `click()`, `fill(v)`, `waitFor()`, `textContent()`. Implicit ARIA roles and accessible names; hidden elements never match a role |
|
|
48
48
|
| `page.frameLocator(iframeSelector)` | Same locators inside an iframe, same- or cross-origin; nest with `.frameLocator()` |
|
|
49
|
-
| `page.evaluate(expression)` | `
|
|
49
|
+
| `page.evaluate(fn, arg?)` / `page.evaluate(expression)` | Runs a function with a JSON-serializable `arg`, or a string expression, in the page. Awaits promises and returns JSON. As in Playwright, the function is sent as source text, so it can't use variables from Node. A thrown JS error rejects with its message and stack |
|
|
50
50
|
| `page.screenshot({ fullPage? })` | PNG `Buffer` |
|
|
51
51
|
| `page.setViewportSize({ width, height })` | CSS-pixel viewport for this page |
|
|
52
52
|
| `page.waitForSelector(selector)` | Waits until visible (Playwright's default state) |
|
|
53
53
|
| `page.close()` / `browser.close()` | Dispose context / shut down |
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
Close pages when a job is done. A page you forget is cleaned up when Node garbage-collects it, which may be much later.
|
|
56
|
+
|
|
57
|
+
See `MISSING.md` for Playwright features that are planned or out of scope.
|
|
58
|
+
|
|
59
|
+
## Develop
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm install
|
|
63
|
+
npm run build # needs Rust
|
|
64
|
+
npm test # smoke test against a real Chrome
|
|
65
|
+
```
|
|
56
66
|
|
|
57
67
|
## License
|
|
58
68
|
|
package/addon.d.ts
CHANGED
|
@@ -2,4 +2,16 @@ export * from './index'
|
|
|
2
2
|
import { Chromium } from './index'
|
|
3
3
|
/** Playwright-style export: `chromium.launch(...)`. Same as `Chromium.launch`. */
|
|
4
4
|
export const chromium: typeof Chromium
|
|
5
|
-
|
|
5
|
+
declare const fluxwright: { chromium: typeof Chromium }
|
|
6
|
+
export default fluxwright
|
|
7
|
+
|
|
8
|
+
declare module './index' {
|
|
9
|
+
interface Page {
|
|
10
|
+
/**
|
|
11
|
+
* Runs `pageFunction` in the page with `arg` and returns its result, awaiting promises.
|
|
12
|
+
* As in Playwright, the function is sent as source text: it can use `arg` (JSON-serializable)
|
|
13
|
+
* but not variables from Node.
|
|
14
|
+
*/
|
|
15
|
+
evaluate<R, Arg = undefined>(pageFunction: (arg: Arg) => R, arg?: Arg): Promise<Awaited<R>>
|
|
16
|
+
}
|
|
17
|
+
}
|
package/addon.js
CHANGED
|
@@ -1,7 +1,44 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { Script } = require('node:vm')
|
|
4
|
+
|
|
5
|
+
// Playwright-style `page.evaluate(fn, arg)`. As in Playwright, the function is sent to the page as
|
|
6
|
+
// source text, so it can use `arg` but not variables from Node. Strings run as expressions.
|
|
7
|
+
function toExpression(pageFunction, arg) {
|
|
8
|
+
if (typeof pageFunction !== 'function') return pageFunction
|
|
9
|
+
return `(${functionSource(pageFunction)})(${arg === undefined ? '' : JSON.stringify(arg)})`
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Object and class methods stringify as `name(x) { ... }`, which is not an expression on its own.
|
|
13
|
+
// Like Playwright, turn them into function expressions (this also covers async and generator methods).
|
|
14
|
+
function functionSource(fn) {
|
|
15
|
+
let source = String(fn)
|
|
16
|
+
if (!parses(source)) {
|
|
17
|
+
source = source.startsWith('async ') ? `async function ${source.slice(6)}` : `function ${source}`
|
|
18
|
+
if (!parses(source)) {
|
|
19
|
+
throw new TypeError(`evaluate: this function can't be sent to the page: ${String(fn).slice(0, 60)}`)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return source
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Compiles only, nothing runs. Unlike `new Function`, this also works under
|
|
26
|
+
// `--disallow-code-generation-from-strings`.
|
|
27
|
+
function parses(source) {
|
|
28
|
+
try {
|
|
29
|
+
new Script(`(${source})`)
|
|
30
|
+
return true
|
|
31
|
+
} catch {
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
3
36
|
try {
|
|
4
37
|
const native = require('./index.js')
|
|
38
|
+
const evaluate = native.Page.prototype.evaluate
|
|
39
|
+
native.Page.prototype.evaluate = async function (pageFunction, arg) {
|
|
40
|
+
return evaluate.call(this, toExpression(pageFunction, arg))
|
|
41
|
+
}
|
|
5
42
|
module.exports = native
|
|
6
43
|
module.exports.chromium = native.Chromium
|
|
7
44
|
module.exports.default = module.exports
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fluxwright",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Run hundreds of headless Chrome jobs on one machine: pooling, queueing, recycling and crash recovery, with a Playwright-style API.",
|
|
5
5
|
"main": "addon.js",
|
|
6
6
|
"types": "addon.d.ts",
|
|
7
7
|
"repository": {
|
|
@@ -9,16 +9,20 @@
|
|
|
9
9
|
"url": "git+https://github.com/harshit-d3v/fluxwright.git",
|
|
10
10
|
"directory": "bindings/node"
|
|
11
11
|
},
|
|
12
|
-
"homepage": "https://
|
|
12
|
+
"homepage": "https://fluxwright.vercel.app",
|
|
13
13
|
"bugs": {
|
|
14
14
|
"url": "https://github.com/harshit-d3v/fluxwright/issues"
|
|
15
15
|
},
|
|
16
16
|
"keywords": [
|
|
17
17
|
"chromium",
|
|
18
18
|
"chrome",
|
|
19
|
-
"
|
|
19
|
+
"headless",
|
|
20
|
+
"playwright",
|
|
21
|
+
"puppeteer",
|
|
20
22
|
"browser-pool",
|
|
21
|
-
"automation",
|
|
23
|
+
"browser-automation",
|
|
24
|
+
"scraping",
|
|
25
|
+
"cdp",
|
|
22
26
|
"napi-rs"
|
|
23
27
|
],
|
|
24
28
|
"author": "Fluxwright contributors",
|
|
@@ -37,6 +41,8 @@
|
|
|
37
41
|
],
|
|
38
42
|
"scripts": {
|
|
39
43
|
"build": "napi build --platform --release",
|
|
44
|
+
"test": "node test/smoke.mjs",
|
|
45
|
+
"test:types": "tsc -p test",
|
|
40
46
|
"build:debug": "napi build --platform",
|
|
41
47
|
"artifacts": "napi artifacts",
|
|
42
48
|
"prepublishOnly": "napi prepublish -t npm --skip-gh-release"
|
|
@@ -54,12 +60,14 @@
|
|
|
54
60
|
"access": "public"
|
|
55
61
|
},
|
|
56
62
|
"devDependencies": {
|
|
57
|
-
"@napi-rs/cli": "^2.18.4"
|
|
63
|
+
"@napi-rs/cli": "^2.18.4",
|
|
64
|
+
"@types/node": "^22.20.4",
|
|
65
|
+
"typescript": "^5.9.3"
|
|
58
66
|
},
|
|
59
67
|
"optionalDependencies": {
|
|
60
|
-
"fluxwright-darwin-arm64": "0.2.
|
|
61
|
-
"fluxwright-darwin-x64": "0.2.
|
|
62
|
-
"fluxwright-linux-x64-gnu": "0.2.
|
|
63
|
-
"fluxwright-win32-x64-msvc": "0.2.
|
|
68
|
+
"fluxwright-darwin-arm64": "0.2.2",
|
|
69
|
+
"fluxwright-darwin-x64": "0.2.2",
|
|
70
|
+
"fluxwright-linux-x64-gnu": "0.2.2",
|
|
71
|
+
"fluxwright-win32-x64-msvc": "0.2.2"
|
|
64
72
|
}
|
|
65
73
|
}
|