How to use Chrome profile in Selenium (selenium-webdriver) JavaScript - javascript

Since there doesn't seem to be a way to use an existing Chrome window, how do I use the Google account (and all settings and passwords) of the user in the window that Selenium opens? Selenium seems to open windows for itself, but without a Google account, which is an essential part to my program.
My program is very time sensitive, so it needs to be logged in to the websites it accesses automatically, and the program is going to be used by multiple users.

var webdriver = require("selenium-webdriver");
var chrome = require("selenium-webdriver/chrome");
var options = new chrome.Options();
options.addArguments("user-data-dir=C:\\Users\robert.car\\AppData\\Local\\Google\\Chrome\\User Data")
options.addArguments("profile-directory=Profile 1")
var driver = let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.build();
user-data-dir considers profile as default , and you don't have to specify that . If its something else specify it through profile-directory argument
Step to create a profile:
open : chrome://version in address bar
copy the user dir folder completely to eg c:\tmp\newdir
open the copied user data (newdir) and search for folder called Default . This is the profile folder.
rename the Default folder as "Profile 1"
Now to use this :
options.addArguments("user-data-dir=c:\\tmp\\newdir")
options.addArguments("profile-directory=Profile 1")

Related

Javascript : Chrome capabilities for "default download directory", "download.prompt_for_download", and "plugins.always_open_pdf_externally"

want to know how to set below capabilities of chrome in javascript. I know Java and python but want in javascript.
Javascript : Chrome capabilities
"default download directory"
"download.prompt_for_download"
"download.directory_upgrade"
"plugins.always_open_pdf_externally"
python code
options = webdriver.ChromeOptions()
options.add_experimental_option('prefs', {
"download.default_directory": "C:/Users/517/Download", #Change default directory for downloads
"download.prompt_for_download": False, #To auto download the file
"download.directory_upgrade": True,
"plugins.always_open_pdf_externally": True #It will not show PDF directly in chrome
})
driver = webdriver.Chrome(options=options)
If possible provide link where I can refer for javascript.
Based on this api-docs, I am able to set capabilities in Javascript except default download path. However, same can be achieved by await wdriver.setDownloadPath('C:\\Downloads');
var chrome = require("selenium-webdriver/chrome");
let downloadFilepath = "C:\\Downloads";
let options = await new chrome.Options();
options.addArguments("--disable-dev-shm-usage");
options.addArguments('--ignore-certificate-errors');
options.addArguments('--ignore-ssl-errors');
options.setUserPreferences({'download.default_directory': "C:\\Downloads"});
options.setUserPreferences({'download.prompt_for_download': false});
options.setUserPreferences({'download.directory_upgrade': true});
options.setUserPreferences({'plugins.always_open_pdf_externally': true});
driver = await chrome.Driver.createSession(options);
Let me know if "download.default_directory" can be set using capabilities instead of wdriver.setDownloadPath.

how to open a firefox browser through selenium 3.6.0 with another profile using Javascript

I want to launch the Firefox browser through selenium-webdriver 3.6.0 with some of the default settings of the browser changed. Specifically, I want Firefox to download files, during automated testing, without prompting whether to save or not and to download to a predefined directory other than the default, which is the downloads folder.
The way to do it on google chrome is this:
if (this.bName === 'chrome') {
var cap = Capabilities.chrome();
var options = {
'prefs': {
profile: {
default_content_settings: {
popups: 0,
},
},
download: {
default_directory: path.join(__dirname,
'/../Downloads For Testing'),
}
}
};
var cap = cap.set('chromeOptions', options);
this.browser = new Builder().withCapabilities(cap).build();
}
A relevant try on Firefox, by setting the preferences after creating a new profile, didn't work.
I include the Profile from Firefox folder
firefoxProfile = require('selenium-webdriver/firefox').Profile;
and I build with new capabilities
else if (this.bName === 'firefox') {
var cap = Capabilities.firefox();
var profile = new firefoxProfile;
profile.setPreference("browser.download.folderList", 2);
profile.setPreference("browser.download.manager.showWhenStarting", false);
profile.setPreference("browser.download.dir", path.join(__dirname, '/../Downloads For Testing'));
profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "text/html");
cap.set('firefox_profile', profile);
console.log(profile);
this.browser = new Builder().withCapabilities(cap).build();
}
This is the printout of the new profile object:
Profile {
preferences_:
{ 'browser.download.folderList': 2,
'browser.download.manager.showWhenStarting': false,
'browser.download.dir': 'C:\\path\\Downloads For Testing',
'browser.helperApps.neverAsk.saveToDisk': 'text/html' },
template_: undefined,
extensions_: []
}
The browser is initiated with no errors and all promises are returned correctly by mocha, the test framework, until pressing the button to download a file and the normal dialog shows up, so no success.
The index.js file in selenium-webdriver\firefox states clearly how to create a new profile dynamically and set the preferences.
* The {#linkplain Profile} class may be used to configure the browser profile
* used with WebDriver, with functions to install additional
* {#linkplain Profile#addExtension extensions}, configure browser
* {#linkplain Profile#setPreference preferences}, and more. For example, you
* may wish to include Firebug:
*
* const {Builder} = require('selenium-webdriver');
* const firefox = require('selenium-webdriver/firefox');
*
* let profile = new firefox.Profile();
* profile.addExtension('/path/to/firebug.xpi');
* profile.setPreference('extensions.firebug.showChromeErrors', true);
*
* let options = new firefox.Options().setProfile(profile);
* let driver = new Builder()
* .forBrowser('firefox')
* .setFirefoxOptions(options)
* .build();
It tried it and it didn't work. Obviously I didn't try to add the extension but only to set the 4 preferences written in my question.
What did the trick for me, as a workaround though, was to create a new profile by executing firefox.exe -p on the windows' Run dialog. (Press the windows icon key and R on keyboard to get the run dialog)
After that, I used this new "testing" profile as a template to create a new temporary one dynamically through selenium.
var profile = new firefox.Profile('/pathTo/firefox profile for testing/');
And here is the trick. It appears to be a thing with Firefox and mime types. If the server, sending the file to download, names the file's content-type differently as the Firefox would, the auto save won't happen and the 'save or open file' dialog will appear. Probably for security reasons. The content type can be found here
In my case it's about a csv file and setting profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "text/csv") while the server sends a content-type of text/html and firefox identifies it as TXT file didn't work.
So I edited the handlers.json file inside /pathTo/firefox profile for testing/ by setting the attribute 'ask' of 'text/plain' inside 'mimeTypes' from true to false.
And of course I set as an only preference the path for the file to get downloaded to. Btw this will also create the path, at least the last folder. So my code is:
else if (this.bName === 'firefox') {
var cap = Capabilities.firefox();
var profile = new firefox.Profile('/pathTo/firefox profile for testing/');
profile.setPreference("browser.download.dir", '/pathTo/Downloads For Testing');
let options = new firefox.Options().setProfile(profile);
this.browser = new Builder().forBrowser(this.bName).setFirefoxOptions(options).build();
}
You can also try this and not mess with the handler.json (end of page) but didn't work for me.
Or just go brute force, this didn't either.

Call Javascript from VBA on Excel on a Mac

I want to create a VBA macro on excel which at a click of button would open a browser (chrome or safari) login to a website, extract the desired float value, then populate a given cell in the sheet with that value.
There are examples online on how to achieve this using internet explorer but this is not available as on a mac. I have also seen guides using Selenium but this doesn't appear to work on mac.
The javascript itself is along the lines of (after opening a browser at a certain website):
document.getElementById("username").value = "username"
document.getElementById("password").value = "password"
document.getElementsByClassName("button")[0].click()
value = parseFloat(document.getElementsByClassName("value")[1].innerText.slice(1))
I've solved this by using a combination of python-selenium and xlwings. My VBA calls RunPython ("import python_script; python_script.fun()")
python_script.py
import xlwings as xw
from selenium import webdriver
def fun():
# Creates a reference to the calling Excel file
wb = xw.Book.caller()
# opens chrome
chrome_driver_path = '/usr/local/bin/chromedriver'
driver = webdriver.Chrome(chrome_driver_path)
# open website and login
driver.get('url')
driver.find_element_by_id('username').send_keys('username')
driver.find_element_by_id('password').send_keys('password')
driver.find_element_by_name('buttonId').click()
# finds member price sum
table_body = driver.find_element_by_xpath("//*[#class='classname']").text
price = float(table_body.split()[2][1:])
# closes chrome
driver.quit()
# changes cell value
sheet = wb.sheets['sheetname']
sheet.range('cell').value = price

How to read and write to a file (Javascript) in ui automation?

I want to identify few properties during my run and form a json object which I would like to write to a ".json"file and save it on the disk.
var target = UIATarget.localTarget();
var properties = new Object();
var jsonObjectToRecord = {"properties":properties}
jsonObjectToRecord.properties.name = "My App"
UIALogger.logMessage("Pretty Print TEST Log"+jsonObjectToRecord.properties.name);
var str = JSON.stringify(jsonObjectToRecord)
UIALogger.logMessage(str);
// -- CODE TO WRITE THIS JSON TO A FILE AND SAVE ON THE DISK --
I tried :
// Sample code to see if it is possible to write data
// onto some file from my automation script
function WriteToFile()
{
set fso = CreateObject("Scripting.FileSystemObject");
set s = fso.CreateTextFile("/Volumes/DEV/test.txt", True);
s.writeline("HI");
s.writeline("Bye");
s.writeline("-----------------------------");
s.Close();
}
AND
function WriteFile()
{
// Create an instance of StreamWriter to write text to a file.
sw = new StreamWriter("TestFile.txt");
// Add some text to the file.
sw.Write("This is the ");
sw.WriteLine("header for the file.");
sw.WriteLine("-------------------");
// Arbitrary objects can also be written to the file.
sw.Write("The date is: ");
sw.WriteLine(DateTime.Now);
sw.Close();
}
But still unable to read and write data to file from ui automation instruments
Possible Workaround ??
To redirect to the stdout if we can execute a terminal command from my ui automation script. So can we execute a terminal command from the script ?
Haven't Tried :
1. Assuming we can include the library that have those methods and give it a try .
Your assumptions are good, But the XCode UI Automation script is not a full JavaScript.
I don't think you can simply program a normal browser based JavaScript in the XCode UI Automation script.
set fso = CreateObject("Scripting.FileSystemObject");
Is not a JavaScript, it is VBScript which will only work in Microsoft Platforms and testing tools like QTP.
Scripting.FileSystemObject
Is an ActiveX object which only exists in Microsoft Windows
Only few JavaScript functions like basic Math, Array,...etc..Are provided by the Apple JavaScript library, so you are limited to use only the classes provided here https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef/
If you want to do more scripting then Try Selenium IOS Driver http://ios-driver.github.io/ios-driver/
Hey so this is something that I was looking into for a project but never fully got around to implementing so this answer will be more of a guide of what to do than step by step copy and paste.
First you're going to need to create a bash script that writes to a file. This can be as simple as
!/bin/bash
echo $1 >> ${filename.json}
Then you call this from inside your Xcode Instruments UIAutomation tool with
var target = UIATarget.localTarget();
var host = target.host();
var result = host.performTaskWithPathArgumentsTimeout("your/script/path", ["Object description in JSON format"], 5);
Then after your automation ends you can load up the file path on your computer to look at the results.
EDIT: This will enable to write to a file line by line but the actual JSON formatting will be up to you. Looking at some examples I don't think it would be difficult to implement but obviously you'll need to give it some thought at first.

Auto Save a file in Firefox

I am trying to find a way where by we can auto save a file in Firefox using JS. The way I have done till yet using FireShot on a Windows Desktop:
var element = content.document.createElement("FireShotDataElement");
element.setAttribute("Entire", EntirePage);
element.setAttribute("Action", Action);
element.setAttribute("Key", Key);
element.setAttribute("BASE64Content", "");
element.setAttribute("Data", Data);
element.setAttribute("Document", content.document);
if (typeof(CapturedFrameId) != "undefined")
element.setAttribute("CapturedFrameId", CapturedFrameId);
content.document.documentElement.appendChild(element);
var evt = content.document.createEvent("Events");
evt.initEvent("capturePageEvt", true, false);
element.dispatchEvent(evt);
But the issue is that it opens a dialog box to confirm the local drive location details. Is there a way I can hard code the local drive storage location and auto save the file?
If you are creating a Firefox add-on then FileUtils and NetUtil.asyncCopy are your friends:
Components.utils.import("resource://gre/modules/FileUtils.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");
var TEST_DATA = "this is a test string";
var source = Components.classes["#mozilla.org/io/string-input-stream;1"].
createInstance(Components.interfaces.nsIStringInputStream);
source.setData(TEST_DATA, TEST_DATA.length);
var file = new FileUtils.File("c:\\foo\\bar.txt");
var sink = file.openSafeFileOutputStream(file, FileUtils.MODE_WRONLY |
FileUtils.MODE_CREATE);
NetUtil.asyncCopy(source, sink);
This will asynchronously write the string this is a test string into the file c:\foo\bar.txt. Note that NetUtil.asyncCopy closes both streams automatically, you don't need to do it. However, you might want to pass a function as third parameter to this method - it will be called when the write operation is finished.
See also: Code snippets, writing to a file
Every computer has a different file structure. But still, there is a way. You can save it to cookie / session, depends on how "permanent" your data wants to be.
Do not consider writing a physical file as it requires extra permission.

Categories

Resources