saucelabs / foxdriver Goto Github PK
View Code? Open in Web Editor NEWFoxdriver is a Node library which provides a high-level API to control Firefox over the Remote Debugging Protocol
License: Apache License 2.0
Foxdriver is a Node library which provides a high-level API to control Firefox over the Remote Debugging Protocol
License: Apache License 2.0
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?)
Surprised not to see actors for typical things like elements + actions. Any reason why these are/were left out?
Here's some references:
Eg:
launch({
args: ['--profile', './profile-dir']
})
In the profile, I've manually set the prefs from:
https://github.com/saucelabs/foxdriver/blob/master/lib/config/profile/prefs.js
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?
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.
Is it possible to create a method just like browser.openTab()
?
It searches for google-chrome instead of firefox (which isn't installed), so it crashes.
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)
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?
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.
I'd like to be able to intercept requests to a certain tab, and block/abort some of them, just like Puppeteer's page.setRequestInterception.
Is this something we can do? I'd love to help with this
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:
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 } }) }
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
With the new quantum it seems that the profile can't be set when using the launch command.
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);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.