Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

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 2 months ago
JSON representation

🦊 Node.js API to control Firefox

Awesome Lists containing this project

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.

logo

* 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) API

At 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
} & TConnectOptions

foxr.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)