How to import safari webdriver from selenium npm package? - node.js

I am trying to load webpage in Safari via Webdriver in Selenium. As per Selenium documentation Safari is inbuilt, but not able to find any docs on how to do that in NodeJS.
Selenium officially supported browser list:
There is sample code of usage on chrome driver as below:
const {Builder} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const service = new chrome.ServiceBuilder('/path/to/chromedriver');
const driver = new Builder().forBrowser('chrome').setChromeService(service).build();
But not able to find anythin specific to safari. So it would be great if someone can help me understanding how to import safari webdriver from selenium npm package and use it for simulating webpage loading?
I did found some doc from Apple, "Testing with WebDriver in Safari", related to the same but in Python(?)

from my Mac M1, enable first
/usr/bin/safaridriver --enable
then
const {Builder, By, Key, until} = require('selenium-webdriver');
(async function example() {
let driver = await new Builder().forBrowser('safari').build();
try {
await driver.get('https://www.google.com');
} finally {
await driver.quit();
}
})();

Related

Add options to selenium chrome browser using nodejs

I am using selenium with Node.js in this way
import {Builder, Browser, By, Key, until} from "selenium-webdriver";
let driver = await new Builder().forBrowser(Browser.CHROME).build();
I want to add chrome options in this way
const chrome = require('selenium-webdriver/chrome')
const options = new chrome.Options()
options.addArguments('--disable-dev-shm-usage')
options.addArguments('--no-sandbox')
options.addArguments('--headless')
let driver = await new Builder().forBrowser(Browser.CHROME).setChromeOptions(options).build();
But I can only use imports in my project, I can't use require. I get the following error because of this line
const chrome = require('selenium-webdriver/chrome')
require is not defined in ES module scope, you can use import instead
How can I import chrome instead of require it to add the option? I am importing a lot of module in my code, It will be really difficult to change them all to requires
You can refer to the file as "selenium-webdriver/chrome.js". I.e.:
import {Options} from "selenium-webdriver/chrome.js";
const options = new Options();
// use options as you always would...

Why chromium doesn't open in headless Mode?

I have the following NodeJS code to open Chromium in headless mode and record a web page to a video :
const { launch, getStream } = require("puppeteer-stream");
const fs = require("fs");
const { exec } = require("child_process");
async function test() {
const browser = await launch({headless: true});
const page = await browser.newPage();
await page.goto("https://www.someurl.com");
const stream = await getStream(page, { audio: true, video: true});
// record the web page to mp4 video
const ffmpeg = exec('ffmpeg -y -i - output.mp4');
stream.pipe(ffmpeg.stdin);
setTimeout(async () => {
await stream.destroy();
stream.on("end", () => {});
}, 1000 * 60);
}
The following code works properly but doesn't open chromium in headless mode. No matter what I do, the browser is still opened and visible when browsing the page. No error is thrown.
Does anyone know why it's not opened in headless mode please ?
Thanks
It says in the documentation for puppeteer-stream:
Notice: This will only work in headful mode
This is due to a limitation of Chromium where the Tab Capture API for the extension doesn't work in headless mode. (There are a couple bug reports about this, but I can't find the links at the moment.)
I had the same issue that headless doesn't work with some Websites and Elements (showing blank page content, not finding an element etc.).
But there is another method to "simulate" the headless mode by minimizing and moving the window to a location that can not be seen by the user.
This doesn't hide the chrome task from the taskbar, but the Chrome tab itself will still be hidden for the User.
Just use the following arguments:
var chromeOptions = new ChromeOptions();
chromeOptions.AddArguments(new List<string>() { "--window-size=1,1", "window-position=-2000,0" }); // This hides the chrome window
var chromeDriverService = ChromeDriverService.CreateDefaultService();
chromeDriverService.HideCommandPromptWindow = true; // This is to hid the console.
ChromeDriver driver = new ChromeDriver(chromeDriverService, chromeOptions);
driver.Navigate().GoToUrl("https://google.com");
in short the important part:
chromeOptions.AddArguments(new List<string>() { "--window-size=1,1", "window-position=-2000,0" });
chromeDriverService.HideCommandPromptWindow = true;
//driver.Manage().Window.Minimize(); //use this if the code above does not work

Proxies in selenium node js

I have been trying for past few days to build a selenium browser with proxies in node.js. I have researched the topic and none of the provided solutions worked for me because they were deprecated or outdated. I have tried different plugins and methods. Could someone answered me with the correct code example or linked me to a solution.
Here you go
const { Builder } = require('selenium-webdriver')
const chrome = require('selenium-webdriver/chrome')
const PROXY = "190.60.104.218:3128"
const option = new chrome.Options().addArguments(`--proxy-server=http://${PROXY}`)
const driver = new Builder().forBrowser('chrome').setChromeOptions(option).build()
driver.get('http://httpbin.org/ip')
.then(() => console.log('DONE'))
Proxy is not anonymous so the original IP is also appearing

Enable Chrome Extension in Puppeteer version 10.1.0

I am attempting to open Chrome with Puppeteer enabling a Chrome extension.
I have been searching for solutions and have tried to implement many with no success.
chrome://version/
Google Chrome: 91.0.4472.164 (Official Build) (x86_64)
Revision: 541163496c9982c98f61819bab7cf2183ea8180f-refs/branch-heads/4472#{#1569}
OS: macOS Version 10.15.7
JavaScript: V8 9.1.269.39
Executable Path: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
Puppeteer: 10.1.0
Code (one of many attempts, but latest):
const puppeteer = require('puppeteer');
const path = require('path');
const extension_id_string = 'copjnifc....example.....gaodgpbh';
const extension_version = '1.5.1_0';
const extension_path = path.resolve(__dirname, '../../..', `/Library/Application\ Support/Google/Chrome/Default/Extensions/${extension_id_string}/${extension_version}`);
(async() => {
const browser = await puppeteer.launch({
headless: false,
args: [
`--load-extension=${extension_path}`,
`--disable-extensions-except=${extension_path}`
]
})
const page = await browser.newPage()
await page.goto('http://google.com');
})();
I've used Node JS path module to get absolute path to the extensions directory.
On running the code with Node v14.17.1 Chromium opens a browser and an alert pops up saying:
alert => Failed to load extension from: . Manifest file is missing or unreadable
When I follow the extension_path (denoted above on line 6) in terminal I can see a Manifest.json file, so there is one.
What am I missing here? Am I defining the path to the extension incorrectly? Or do I need to set the executablePath for my current Chrome path inside the options when launching a browser? (I did try this with no success).
const chrome_executablePath = path.resolve(__dirname, '../../..', '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome')
...
const browser = await puppeteer.launch({
headless: false,
executablePath: chrome_executablePath, //<-- added this line in previous attempts, but still didn't work
args: [
`--load-extension=${extension_path}`,
`--disable-extensions-except=${extension_path}`
]
})
...
Any pointers / help greatly appreciated.
I think you can do three things here:
Check if the manifest.json is encoded to UTF-8.
Make sure your extension path points to the extension area (i.e development area).
After headless false, add "devtools: true" option.

How to download a CSV file with selenium while bypassing the file dialog

I have been trying to access a url with a CSV file to download it in a specific directory, using the Selenium Webdriver for Firefox(geckodriver), in a NodeJS enviroment on Linux-Mint.
This is my code:
const {Builder} = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');
const path = require('path');
const options = new firefox.Options();
options.setPreference('browser.download.dir', path.resolve(__dirname));
options.setPreference('browser.download.folderList', 2);
options.setPreference('browser.helperApps.neverAsk.saveToDisk', 'application/x-csv');
function example(){
let driver = new Builder().forBrowser('firefox').setFirefoxOptions(options).build();
driver.get('http://insight.dev.schoolwires.com/HelpAssets/C2Assets/C2Files/C2ImportCalEventSample.csv');
}
example();
As you can see, I am correctly setting the browser option to browser.helperApps.neverAsk.saveToDisk, so as to be able to bypass the dialog. However, I am still getting the dialog no matter what I do. I haven't tried this code on Windows, but for my purposes it needs to work on Linux.
Am I missing something? Some preference that needs to be added or changed? Or does this not work on my current enviroment?
Thank you in advance for any help provided.
If you are just downloading a file from link why do you need selenium?
A much simple approach will be just to get the file by http and save to file.
const http = require('http');
const fs = require('fs');
const file = fs.createWriteStream("C2ImportCalEventSample.csv");
const request = http.get("http://insight.dev.schoolwires.com/HelpAssets/C2Assets/C2Files/C2ImportCalEventSample.csv", function(response) {
response.pipe(file);
});
If you have to use selenium let me know in the comments and i will try to find a solution for your problem using selenium.

Resources