GithubHelp home page GithubHelp logo

saucelabs / foxdriver Goto Github PK

View Code? Open in Web Editor NEW
66.0 66.0 10.0 1.78 MB

Foxdriver is a Node library which provides a high-level API to control Firefox over the Remote Debugging Protocol

License: Apache License 2.0

JavaScript 100.00%

foxdriver's People

Contributors

benmalka avatar cbrecabarren avatar christian-bromann avatar dependabot[bot] avatar farhan-sauce avatar mciastek avatar oss-sauce-bot avatar yfangsl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

foxdriver's Issues

How to take screenshot?

Hello, I was curious as to how I can take a screenshot using foxdriver? AFAIK it doesnt expose the device domain, nor would it work (?) because the tab doesn't contain a device actor (does a device domain even exist in the protocol?)

Taking a heap snapshot

Hi,

I am trying to take a heap snapshot with foxdriver like so:

const Foxdriver = require('foxdriver')

;(async function() {
    const { browser, tab } = await Foxdriver.attach('localhost', 6000)
    await browser.tabs[0].memory.attach()
    const id = await browser.tabs[0].memory.saveHeapSnapshot()
    console.log(id)
    const snapshot = await browser.heapSnapshotFile.getHeapSnapshot(id)
    // console.log(snapshot)
    browser.tabs[0].memory.detach()
    browser.disconnect()
})()

However this seem to hang at line browser.heapSnapshotFile.getHeapSnapshot

What am I doing wrong?

Error when trying to remotely execute JS in the browser

I am trying to use this library to remotely control netflix while building my own "smart tv". I am testing evaluating simple JS:

        const { browser, tab } = await Foxdriver.launch({
            url: 'https://www.netflix.com',
            bin: firefoxPath
        });
        await tab.console.startListeners();
        await new Promise((resolve) => setTimeout(resolve, 20000));
        console.log(await tab.console.evaluateJS("window.location.hash = \"blablabla\""));

The error:

(node:271348) UnhandledPromiseRejectionWarning: Error: this.parentActor.threadActor is undefined (unknownError)
    at D:\JAKUB\programming\node-smart-tv\SmartTV\node_modules\foxdriver\build\actor.js:61:23
    at Generator.next (<anonymous>)
    at step (D:\JAKUB\programming\node-smart-tv\SmartTV\node_modules\babel-runtime\helpers\asyncToGenerator.js:17:30)
    at D:\JAKUB\programming\node-smart-tv\SmartTV\node_modules\babel-runtime\helpers\asyncToGenerator.js:28:13
    at process._tickCallback (internal/process/next_tick.js:68:7)

What's wrong? I need to evaluate commands to control the player.

Doesn't work on linux

It searches for google-chrome instead of firefox (which isn't installed), so it crashes.

Errors from tab.navigateTo() in Firefox versions > 56

tab.navigateTo() works fine in 56 (release channel) for me, but 57 (beta channel, currently) and 58 (nightly, currently) both give the same error:

Error: No such actor for ID: server1.conn1.child1/tab1 (noSuchActor)
at /Users/dietrich/Dropbox/misc/quantum/node_modules/foxdriver/build/actor.js:61:23
at Generator.next ()
at step (/Users/dietrich/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
at /Users/dietrich/node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13
at process._tickCallback (internal/process/next_tick.js:109:7)

Error: Actor <> does not recognize the packet type 'attach' (unrecognizedPacketType)

I am trying to run just the POC code from the readme (Mac M1, macOS 12, Firefox 99, foxdriver 1.0.6), but get:

/ff/node_modules/foxdriver/build/actor.js:44
      throw new Error(`${result.message} (${result.error})`);
            ^

Error: Actor server1.conn1.child3/windowGlobalTarget2 does not recognize the packet type 'attach' (unrecognizedPacketType)
    at Tab.request (/ff/node_modules/foxdriver/build/actor.js:44:13)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async file:///ff/index.js:16:5

Google hasn't helped. Can anyone help me understand what I may be doing wrong?

Problems with attaching on Windows

This perhaps should be several separate issues, but I'm in a hurry, and figured it's better to report anything, than nothing, so...
I've tried to follow the example from the Readme, to attach to already running browser.
First I've got a problem with the import not really being supported:

(node:8696) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
C:\dev\fbscrap\go.js:1
import Foxdriver from 'foxdriver';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1026:15)
    at Module._compile (node:internal/modules/cjs/loader:1061:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
    at Module.load (node:internal/modules/cjs/loader:975:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:17:47

Node.js v17.1.0

so I've changed it to const Foxdriver = require('foxdriver');.

Then it turned out that there's some hidden dependency on babel:

node:internal/modules/cjs/loader:933
  const err = new Error(message);
              ^

Error: Cannot find module '@babel/runtime/helpers/interopRequireDefault'
Require stack:
- C:\dev\fbscrap\node_modules\foxdriver\build\index.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:999:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (C:\dev\fbscrap\node_modules\foxdriver\build\index.js:3:30)
    at Module._compile (node:internal/modules/cjs/loader:1097:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
    at Module.load (node:internal/modules/cjs/loader:975:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:190:29) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ 'C:\\dev\\fbscrap\\node_modules\\foxdriver\\build\\index.js' ]
}

Node.js v17.1.0

I've fixed it with

$ npm add @babel/runtime
$ npm install

Then it had trouble to attach:
await Foxdriver.attach('localhost',9222);
from the example, didn't work for me. It tried to use IPv6, I guess, from the error message

node:events:368
      throw er; // Unhandled 'error' event
      ^

Error: connect ECONNREFUSED ::1:9222
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)
Emitted 'error' event on Browser instance at:
    at Client.<anonymous> (C:\dev\fbscrap\node_modules\foxdriver\build\browser.js:23:38)
    at Client.emit (node:events:390:28)
    at Client.onError (C:\dev\fbscrap\node_modules\foxdriver\build\client.js:278:10)
    at Socket.emit (node:events:390:28)
    at emitErrorNT (node:internal/streams/destroy:164:8)
    at emitErrorCloseNT (node:internal/streams/destroy:129:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  errno: -4078,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '::1',
  port: 9222
}

Node.js v17.1.0

What did work for me was: "127.0.0.1" in place of "localhost".

Then it turned out that the example code and the documentation for attach() shows that the result of attach should have a tab field, but in reality it has tabs.
So I had to change :

const {browser,tab} = await Foxdriver.attach('127.0.0.1',9222);

to

const {browser,tabs} = await Foxdriver.attach('127.0.0.1',9222);
const tab=tabs[0];

I had an issue with using tab.console.evaluateJS - it's marked as "deprecated", but actually it doesn't work at all.
So, I've switched to tab.console.evaluateJSAsync, and then it worked, with one gotcha.

I needed to execute an asynchronous code inside the browser, and await for the result.
I've tried async function go(){...do some stuff}; await go(), but it failed with

Error: SyntaxError: await is only valid in async functions, async generators and modules

this might be specific to Firefox itself, not this project. Anyway, the workaround was to do something like:
go().then((val)=>{window.done=val}) inside the script passed to evaluateJSAsync
and then polling for the result on the node side:

while(!await tab.console.evaluateJSAsync(`return window.done`)){
  await seconds(3);
}
console.log("Finally done!",await tab.console.evaluateJSAsync(`return window.done`));

but I hope it's possible to make the API more ergonomic, or I've missed something.

Error: Cannot find module 'babel-runtime/helpers/asyncToGenerator'

Interesting, this didn't happen before, but happens with a fresh install now.

Error: Cannot find module 'babel-runtime/helpers/asyncToGenerator'
at Function.Module._resolveFilename (module.js:547:15)
at Function.Module._load (module.js:474:25)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object. (/Users/dietrich/misc/puppeteer-fx/node_modules/foxdriver/build/index.js:7:26)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)

After installing babel-runtime, the new error is:

(node:22784) UnhandledPromiseRejectionWarning: Error: TypeError: document.querySelector(...) is null
at /Users/dietrich/misc/puppeteer-fx/node_modules/foxdriver/build/domains/console.js:87:23
at Generator.next ()
at step (/Users/dietrich/misc/puppeteer-fx/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
at /Users/dietrich/misc/puppeteer-fx/node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13
at
at process._tickCallback (internal/process/next_tick.js:188:7)

Some more info here on potential fix:

https://stackoverflow.com/questions/34338416/babelhelpers-asynctogenerator-is-not-a-function-on-react-native-0-16-0-and-0-1#34736520

[Feature request] add "cacheDisabled" method to "Tab"

After some digging, I found that there's a possibility to Enable/Disable the network caching in Firefox, which I use.
Here's what you should add to Tab

cacheDisabled (disable) { return this.request('reconfigure', { options: { cacheDisabled: disable } }) }

evaluateJSAsync Hangs

Hello, this is maybe leaning more towards a question than an issue, so if you have a discord channel or similar, im happy to discuss there, but i can't seem to get evaluateJSAsync to work :/

//
// This block was taken from your README, but only the lines to get logs were moddified, to instead evaluate
//

import Foxdriver from 'foxdriver'

(async () => {
  const { browser, tab } = await Foxdriver.launch({
    url: 'https://www.mozilla.org/en-US'
  });

  // enable actor
  await tab.console.startListeners();
  // wait until page is loaded
  await new Promise((resolve) => setTimeout(resolve, 3000));
  // evaluate
  const result = await tab.console.evaluateJSAsync(`return document.title`); // also tried just `document.title`
  console.log(result);

  // close browser
  browser.close();
})()

But this just hangs. All i'm hoping to do is just evaluate expressions

puppeteer-fx Type Error on Click

I am trying to get puppeteer-fx to work, code below is launching the firefox browser, but i get the TypeError: scope.context.currentPage.click is not a function. Works in Chrome, no issues.
Looks like its not including puppeteer with puppeteer-fx during the runtime? Any suggestions please?

const b = process.env.PUPPETEER_BROWSER || 'chrome';
const puppeteer = b === 'firefox' ?
require('puppeteer-fx') : require('puppeteer')

const World = function() {
scope.driver = puppeteer;
scope.context = {};
};

await scope.context.currentPage.goto(CREDS.url);
await scope.context.currentPage.click(loginpage.loginfields.USERNAME_SELECTOR);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.