Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/deepsweet/foxr
🦊 Node.js API to control Firefox
https://github.com/deepsweet/foxr
firefox headless marionette puppeteer remote selenium
Last synced: about 1 month ago
JSON representation
🦊 Node.js API to control Firefox
- Host: GitHub
- URL: https://github.com/deepsweet/foxr
- Owner: deepsweet
- License: mit
- Archived: true
- Created: 2018-08-09T08:45:28.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-04T21:41:11.000Z (almost 2 years ago)
- Last Synced: 2024-05-12T02:33:11.386Z (6 months ago)
- Topics: firefox, headless, marionette, puppeteer, remote, selenium
- Language: TypeScript
- Size: 1.48 MB
- Stars: 795
- Watchers: 12
- Forks: 19
- Open Issues: 32
-
Metadata Files:
- Readme: readme.md
- License: license.md
Awesome Lists containing this project
- awesome-puppeteer - foxr - Node.js API to control Firefox. 🦊 (Related)
- awesome-list - foxr
README
# foxr
[![npm](https://flat.badgen.net/npm/v/foxr)](https://www.npmjs.com/package/foxr) [![install size](https://flat.badgen.net/packagephobia/install/foxr)](https://packagephobia.now.sh/result?p=foxr) [![tests](https://flat.badgen.net/travis/deepsweet/foxr/master?label=tests)](https://travis-ci.org/deepsweet/foxr) [![coverage](https://flat.badgen.net/codecov/c/github/deepsweet/foxr/master)](https://codecov.io/github/deepsweet/foxr)
Node.js API to control Firefox.
* uses a built-in [Marionette](https://vakila.github.io/blog/marionette-act-i-automation/) through [remote protocol](https://firefox-source-docs.mozilla.org/testing/marionette/marionette/index.html)
* no [Selenium WebDriver](https://github.com/SeleniumHQ/selenium/wiki/FirefoxDriver) is needed
* works with [Headless mode](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode)
* compatible subset of [Puppeteer](https://github.com/GoogleChrome/puppeteer) APIAt this point Foxr is more a proof of concept, [work is pretty much in progress](https://github.com/deepsweet/foxr/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aenhancement).
## Example
Run a locally installed Firefox:
```sh
/path/to/firefox -headless -marionette -safe-mode
```Or a [dockerized version](https://github.com/deepsweet/firefox-headless-remote):
```sh
docker run -it --rm --shm-size 2g -p 2828:2828 deepsweet/firefox-headless-remote:68
``````js
import foxr from 'foxr'
// const foxr = require('foxr').default(async () => {
try {
const browser = await foxr.connect()
const page = await browser.newPage()await page.goto('https://example.com')
await page.screenshot({ path: 'example.png' })
await browser.close()
} catch (error) {
console.error(error)
}
})()
```## Install
```sh
yarn add --dev foxr
# or
npm install --save-dev foxr
```## API
### Foxr
#### `connect`
Connect to the Marionette endpoint.
```ts
type TConnectOptions = {
host?: string,
port?: number,
defaultViewport?: {
width?: number,
height?: number
}
}foxr.connect(options?: TConnectOptions): Promise
```* `host` – `'localhost'` by default
* `port` – `2828` by default
* `defaultViewport`
* `width` – `800` by default
* `height` – `600` by default#### `launch`
```ts
type TLaunchOptions = {
args?: string[],
dumpio?: boolean,
executablePath: string,
headless?: boolean
} & TConnectOptionsfoxr.launch(options?: TLaunchOptions): Promise
```* `args` – array of additional args, `['-marionette', '-safe-mode', '-no-remote']` by default
* `dumpio` – print browser process stdout and stderr, `false` by default
* `executablePath` – path to Firefox executable, required
* `headless` – whether to run browser in headless mode, `true` by default### Browser
#### `close`
```ts
browser.close(): Promise
```#### `disconnect`
```ts
browser.disconnect(): Promise
```#### `newPage`
```ts
browser.newPage(): Promise
```#### `pages`
```ts
browser.pages(): Promise
```#### `install`
```ts
browser.install(extensionPath: string, isTemporary: boolean): Promise
```#### `uninstall`
```ts
browser.install(extensionId: string): Promise
```#### `getPref`
```ts
browser.getPref(pref: string, defaultBranch: boolean = false): Promise
```#### `setPref`
```ts
browser.setPref(pref: string, value: string | number | boolean, defaultBranch: boolean = false): Promise
```### Page
#### `$`
```ts
page.$(selector: string): Promise
```#### `$$`
```ts
page.$$(selector: string): Promise
```#### `$eval`
```ts
page.$eval(selector: string, func: TSerializableFunction, ...args: TEvaluateArg[]): Promise
```#### `$$eval`
```ts
page.$$eval(selector: string, func: TSerializableFunction, ...args: TEvaluateArg[]): Promise>
```#### `bringToFront`
```ts
page.bringToFront(): Promise
```#### `browser`
```ts
page.browser(): TBrowser
```#### `close`
```ts
page.close(): Promise
```#### `content`
```ts
page.content(): Promise
```#### `evaluate`
```ts
page.evaluate(target: string): Promise
page.evaluate(target: TSerializableFunction, ...args: TEvaluateArg[]): Promise
```#### `evaluateHandle`
```ts
page.evaluate(target: string): Promise
page.evaluate(target: TSerializableFunction, ...args: TEvaluateArg[]): Promise
```#### `focus`
```ts
page.focus(selector: string): Promise
```#### `goto`
```ts
page.goto(url: string): Promise
```#### `screenshot`
```ts
page.screenshot(options?: { path?: string }): Promise
```#### `setContent`
```ts
page.setContent(html: string): Promise
```#### `title`
```ts
page.title(): Promise
```#### `url`
```ts
page.url(): Promise
```#### `viewport`
```ts
page.viewport(): Promise<{ width: number, height: number }>
```### JSHandle
…
### ElementHandle
#### `$`
```ts
elementHandle.$(selector: string): Promise
```#### `$$`
```ts
elementHandle.$$(selector: string): Promise
```#### `click`
```ts
type TOptions = {
button?: 'left' | 'middle' | 'right',
clickCount?: number
}elementHandle.click(options?: TOptions): Promise
```#### `focus`
```ts
elementHandle.focus(): Promise
```#### `hover`
```ts
elementHandle.hover(): Promise
```#### `press`
```ts
elementHandle.press(key: string): Promise
```Where `key` is of the [possible keys](./src/keys.ts) or a single character.
#### `screenshot`
```ts
elementHandle.screenshot(options?: { path?: string }): Promise
```#### `type`
```ts
elementHandle.type(text: string): Promise
```## Development
See [my Start task runner preset](https://github.com/deepsweet/_/tree/master/packages/start-preset-node-ts-lib) for details.
## References
* Python Client: [API](https://marionette-client.readthedocs.io/en/latest/reference.html), [source](https://searchfox.org/mozilla-central/source/testing/marionette/client/)
* Perl Client: [API](https://metacpan.org/pod/Firefox::Marionette), [source](https://metacpan.org/source/DDICK/Firefox-Marionette-0.57/lib/Firefox)
* Node.js client (outdated): [source](https://github.com/mozilla-b2g/gaia/tree/master/tests/jsmarionette/client)
* [Marionette Google Group](https://groups.google.com/forum/#!forum/mozilla.tools.marionette)