We use PhantomJS as simple test runner like this:
phantomjs path/to/test.js
Is there a similar way with headless chrome?
Selenium WebDriver is a NPM package that can help you to run a headless browser.
Try the below example:
const chrome = require('selenium-webdriver/chrome');
const {Builder, By, Key, until} = require('selenium-webdriver');
const width = 640;
const height = 480;
let driver = new Builder()
.forBrowser('chrome')
.setChromeOptions(
new chrome.Options().headless().windowSize({width, height}))
.build();
driver.get('http://www.google.com/ncr')
.then(_ =>
driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN))
.then(_ => driver.wait(until.titleIs('webdriver - Google Search'), 1000))
.then(
_ => driver.quit(),
e => driver.quit().then(() => { throw e; }));
According to the API, the driver methods return Promises and, as a result, can be called using the async/await syntax:
const chrome = require('selenium-webdriver/chrome');
const {Builder, By, Key, until} = require('selenium-webdriver');
async function test() {
const width = 640;
const height = 480;
let driver = new Builder()
.forBrowser('chrome')
.setChromeOptions(
new chrome.Options().headless().windowSize({width, height}))
.build();
await driver.get('http://www.google.com/ncr')
await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN))
await driver.wait(until.titleIs('webdriver - Google Search'), 1000))
await driver.quit()
}
test();
You can run you tests with Karma and headless Chrome. Here's a guide for doing that.
Puppeteer's also pretty well-equipped to do this. Here's a guide for that too.
You're looking for Puppeteer, an API for headless Chrome/Chromium.
Once you have your script (the docs are good), you can run it with node script.js.
as explained on developers.google you have option of using Node or Selenium, in either case you will have to re-write part of your test cases to use the new api instead of the phantomjs api.
The following options are based on Node:
Puppeteer
I suggest you to head over to their github page for installation and usage instructions.
Your test case should be written using the Puppetteer api and run with:
node path/to/test.js
There is a list of puppeteer resources, you can use puppeteer with jest, mocha, angular, e2e..
chrome-remote-interface
library
chrome-remote-interface is a lower-level library than Puppeteer's API. I recommend it if you want to be close to the metal and use the DevTools protocol directly.
You need to start chrome in headless mode or use lighthouse or nodejs:
node --inspect=9222 path/to/test.js
write your javascript test case using the chrome DevTools protocol and follow the instructions on their github page to install and run your tests.
The other option is using Selenium configured to run headless Chrome. The following options use Selenium:
ChromeDriver
Webdriver
Related
I've made a node.js script like this:
const { Builder, By, Key, until } = require('selenium-webdriver');
const driver = new Builder().forBrowser("firefox").build();
const search_query = 'tigers';
(async () => {
await driver.get(`https://www.google.com/search?q=${search_query}`);
const h3Elements = await driver.findElements(By.css('h3'));
for (const h3 of h3Elements) {
console.log(await h3.getText());
}
console.log('...Task Complete!')
})();
and now I want to test it on a heroku server
but sadly I have no experience or understanding when it comes to setup
I tried following these link:
How to use Selenium Webdriver on Heroku?
How to run Selenium-Webdriver on Heroku with node.js (Firefox or Chrome)
but neither are for firefox
so how do I launch the above script on a heroku server? and what exactly is the process that is going on when it comes to web drivers on the server?
EDIT
I've added https://github.com/hamitaksln/heroku-integrated-firefox-geckodriver as a build pack
and set configuration vars as such:
FIREFOX_BIN=/app/vendor/firefox/firefox
GECKODRIVER_PATH=/app/vendor/geckodriver/geckodriver
LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:/lib:/app/vendor
PATH=/usr/local/bin:/usr/bin:/bin:/app/vendor/
but it still shows an ERROR of incorrect path to geckodriver
I've tried with Puppeteer v5.4.0, v5.4.1, and v5.5.0, Windows 10/MacOS, and Node v12/v14.0.1/v15.0.3 to try to get Puppeteer to run in Electron.
Doing a simple puppeteer.launch() like this in the main process of a React application:
const puppeteer = require('puppeteer');
(async function(){
const browser = await puppeteer.launch();
})();
returns this:
Uncaught (in promise) Error: Could not find browser revision 818858. Run "PUPPETEER_PRODUCT=firefox npm install" or "PUPPETEER_PRODUCT=firefox yarn install" to download a supported Firefox browser binary.
at ChromeLauncher.launch (Launcher.js:120)
at async http:/localhost:8080/main.js:61295
I've tried running PUPPETEER_PRODUCT=firefox yarn install, setting the executablePath in the launch() method, deleting node_modules and package-lock.json, but none of these solutions seem to work. In the case of setting a path, it returns a ENOENT error. Weird enough, though, writing a small script and running it through node test.js seems to work fine.
After some hours of tinkering, here's how I figured it out:
Instead of calling from the main process, set the function in the renderer process and call it, like this:
/* main.js - Renderer Process */
ipcMain.on('spawn-browser', (event, arg) => {
const browser = await puppeteer.launch();
// Your other functions...
});
And from the main process, you can call something like:
require('electron').ipcRenderer.send('spawn-browser', args);
which works.
According to this, try one of the following:
sudo npm install puppeteer --unsafe-perm=true --allow-root
Or:
for linux:
1- you must have installed chromium browser using this command :
$sudo apt install -y chromium-browser
2- you have to get the excutable path of chromium using this command :
$which chromium-browser
3-put the executable path as an argument to the launch function :
const puppeteer = require('puppeteer-core');
(async () => {
const browser = await puppeteer.launch({
executablePath: '/usr/bin/chromium-browser',
headless: false
});
const page = await browser.newPage();
await page.goto('https://google.com');
await page.screenshot({path: 'example.png'});
await browser.close();
})();
I require this node module selenium-webdriver/chrome to run my script in headless.
I am unable to find this module on https://www.npmjs.com.
From where else I can find this module?
var chrome = require('selenium-webdriver/chrome');
var driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(new chrome.Options().headless().windowSize(screen))
.build();
As Evyatar pointed out to you, the module you're looking for is selenium-webdriver and not selenium-webdriver/chrome, so you're to install npm install selenium-webdriver --save then you require selenium-webdriver.
Example:
const webdriver = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const firefox = require('selenium-webdriver/firefox');
let driver = new webdriver.Builder()
.forBrowser('firefox')
.setChromeOptions(/* ... */)
.setFirefoxOptions(/* ... */)
.build();
This should solve your problem.
You can get to read more on the usage of selenium-webdriver
I have my selenium standalone server set up as running with the IEDriver as a parameter using the selenium-standalone start --drivers.ie.arch=ia32 configuration.
I'm getting the following error when I try to run my internet explorer selenium test:
index.js:673
throw new Error('Do not know how to build driver: ' + browser
^
Error: Do not know how to build driver: IE; did you forget to call
usingServer(url)?
Yet I have the correct server listed in my code:
const {Builder, By, Key, until} = require('selenium-webdriver');
driver = await new webdriver.Builder().forBrowser('IE').usingServer('http://localhost:4444/wd/hub').build();
I have also tried this:
let driver = new webdriver.Builder()
.forBrowser('internet explorer')
.usingServer('http://localhost:4444/wd/hub')
.build();
but neither of these work and I get the same error message...
Any help would be appreciated!
https://github.com/SeleniumHQ/selenium/wiki/Grid2 Just read this article, you are missing something. And run your IE tests under administrator for future.
driver = new webdriver.Builder().
usingServer("http://localhost:4444/wd/hub").
withCapabilities(webdriver.Capabilities.ie()).
build();
It works for me.
I am currently trying to run some tests made with webdriverjs and chromedriver but they need microphone permissions.
This is the popup that shows up:
I have tried:
chromedriver.start(['--disable-popup-blocking']);
driver = new Webdriver.Builder()
.withCapabilities(Webdriver.Capabilities.chrome())
.build();
but it didn't work.
I also tried
driver.wait(Until.alertIsPresent(), config.TIMEOUT, 'Alert did not show up');
driver.switchTo().alert().accept();
it did not work either! I guess that this is not an ordinary alert.
Useful links:
Chrome startup arguments list
Chrome options for java and ruby
Chromedriver github
How do I give them permissions programmatically?
Is there any flag or some other way around this?
A little late but pasting how to do this here for others looking for the same.
const webdriver = require('selenium-webdriver'), By = webdriver.By, until = webdriver.until,Builder= webdriver.Builder;
var chrome = require('selenium-webdriver/chrome');
var chromeOptions = new chrome.Options()
.addArguments('allow-file-access-from-files')
.addArguments('use-fake-device-for-media-stream')
.addArguments('use-fake-ui-for-media-stream');
var driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(chromeOptions);
driver = driver.build();
A fresh profile is loaded each time you run selenium, hence changes you make to the preferences and website permissions are not preserved between sessions. To amend this we need to tell selenium which profile to load.
Step 1. Find your Chrome preferences file: www.forensicswiki.org/wiki/Google_Chrome#Configuration
Step 2. Copy the folder Default somewhere. I will assume it is copied to /some/path/allow-mic/Default.
Alternative Step 3 (this is easier):
Before copying Default visit localhost:1337 with Chrome and set mic to always allow.
Step 3. Edit allow-mic/Default/Preferences, find the tags "profile", "content_settings" and "exceptions" within each other and add
"media_stream_mic":{"http://localhost:1337,*":
{"last_used":1470931206,
"setting":1} },
to "exceptions". You should end up with something like:
...
"profile":{
...
"content_settings": {
...
"exceptions": {
...
"media_stream_mic":{"http://localhost:1337,*":
{"last_used":1470931206,
"setting":1} },
...
},
},
},
...
Step 4:
Configure selenium to use the edited preferences:
var chromedriver = require('chromedriver');
var Webdriver = require('selenium-webdriver');
var chrome = require('selenium-webdriver/chrome');
var opts = new chrome.Options();
opts.addArguments("user-data-dir=/some/path/allow-camera");
var driver = new chrome.Driver(opts);
You can check that the correct set of preferences (Profile path) are in use by opening chrome://version/.
For those using Python, this worked for me:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("--use-fake-ui-for-media-stream")
driver = webdriver.Chrome(chrome_options=chrome_options)
You can whitelist a url for audio-capture by providing chromedriver with the hardware.audio_capture_allowed_urls preference.
...
chrome_options = Options()
prefs = {"hardware.audio_capture_allowed_urls" : ["example.org"]}
chrome_options.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome(chrome_options=chrome_options)
Similarly, for use in Splinter
from splinter import Browser
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("--use-fake-ui-for-media-stream")
Browser('chrome', ** {'executable_path':'chromedriver'},options=chrome_options)
If you want to use the microphone,
chrome_options = Options()
chrome_options.add_experimental_option('prefs',{'profile.default_content_setting_values.media_stream_mic':1})
driver = webdriver.Chrome(path,chrome_options=chrome_options)