how does selenium web driver work in javascript? - javascript

I am trying to scrap a website so I use selenium-webdriver.
I've chosen javascript and nodejs as language to teach myself.
The following is a very basic code to understand the behaviour of the tool.
I launch it with the following command line :
node --debug-brk=5858 src/app.js
var chromedriver = require('chromedriver');
var webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;
var driver = new webdriver.Builder()
.forBrowser('chrome')
.build();
driver.get('http://www.google.com/ncr');
debugger;
driver.findElement(By.name('q')).sendKeys('webdriver');
driver.findElement(By.name('btnG')).click();
driver.wait(until.titleIs('webdriver - Google Search'), 1000);
driver.quit();
I am using vscode as IDE.
When I press F5, after setting a breakpoint in the code, the breakpoint is hit BUT no browser is opened yet. I click on resume (in VScode), the script finishes, and only then the browser is launched and corresponding commands are executed, my breakpoint being now ignored since it has already been hit.
This has the following consequence : I cannot step by step the selenium webdriver and thus am unable to evaluate the content of a find elements with xpath command.
I am missing Something but fail to see what.
Do I have to add Sleep statements ?
I've seen most people use java but I'd rather stick to javascript if possible.

There are a couple of issues that I can see in your program.
When using javascript to program webdriver, an important concept is that all function calls are asynchronous and return a Thenable or Promise. So you cannot write line by line like in sequential programming.
You need to work this way:
driver.findElement(By.name('q')).sendKeys('webdriver')
.then( function(){
driver.findElement(By.name('btnG')).click();
...
});
See WebDriver's javascript API Documentation here:
https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/index.html
In terms of debugging, if you pause in the browser's developer tool and trace there, what you trace is the website program that you are trying to scrape, but not your webdriver program. I use WebStorm to trace my webdriver program.

Related

how to initiate a node js command with a html button?

i am making a PWA for my college portal, so i need an API for HTTPS call, but unfortunately i have no API for that website which i am making for to use the concepts like FETCH API in js or AXIOS. I would rather go with XMLHTTPS request but, its an old one and very complex too. So, i though of using selenium with javascript. and i did it successfully, just installed npm package and i have installed some webdrivers for firefox.and everything is fine, but the whole selenium webdriver is working with a node command.
node file_name
node file_name.js
any syntax is accepted .
const {Builder, By, Key, util}=require("selenium-webdriver");
async function example(){
let driver = await new Builder().forBrowser("firefox").build();
await driver.get("https://login.gitam.edu/Login.aspx"); //this is the link
await driver.findElement(By.name("txtusername")).sendKeys("0116", Key.INSERT);
await driver.findElement(By.name("password")).sendKeys("password", Key.RETURN);
}
example();
now, the above code is operated by node file_name
but i need this from my UI , Which i am making for my PWA. so, i design button, when user click that, it is going to initiate the above selenium javascript snippet.So i need a code or any resource for making that button to initiate the terminal command and that in return makes selenium javascript code to run.
please answer my question.
ps: this is my first question on stackoverflow !!!!
thank you very much.

Unsuccessful in trying to start Selenium IDE recording from C# code

I'm working with Selenium WebDriver (3 latest, Chrome driver, 83 latest) in C# (windows10, .net fw 4.6.2). I'm trying to start the IDE recording from within the code of a running automation test, on the open web page, (my intention is to record all the actions being done within the automation test), but with no success.
I'm trying to do it using the IDE extension API (I don't want that the IDE will be actually open during the test, nor do I want it to reopen the page for recording, since it is already open by the automation test)
My final intention is to use the outcome of the IDE recording for something I need.
Here is my C# code:
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace IDE
{
class Program
{
static void Main(string[] args)
{
ChromeOptions options = new ChromeOptions();
// Load IDE extension to chrome
options.AddExtension(#"C:\Users\<my user name>\Downloads\extension_3_17_0_0.crx");
IWebDriver driver = new ChromeDriver(options);
// Start IDE recording
((IJavaScriptExecutor)driver).ExecuteScript("chrome.runtime.sendMessage(\"mooikfkahbdckldjjndioackbalphokd\", {uri: \"/record/session\", verb: \"post\", payload: {url: 'https://www.google.com'}});");
driver.Navigate().GoToUrl("https://www.google.com");
driver.Manage().Window.Maximize();
// Do some more actions
// ......
// Stop the IDE recording
((IJavaScriptExecutor)driver).ExecuteScript("chrome.runtime.sendMessage(\"mooikfkahbdckldjjndioackbalphokd\", {uri: \"/record/session\", verb: \"delete\"});");
driver.Quit();
}
}
}
I can see that the IDE extension is loaded, but the "chrome.runtime.sendMessage" is always throwing an exception (no matter what I supply as a value to its parameters) : "Cannot read property 'sendMessage' of undefined". The code I pasted here is just an example. I tried many other variations of "chrome.runtime.sendMessage". All of them threw the same exception.
I've seen a few discussions over the net about that exception in relation to my issue, but they all mention some java script files that have to be changed (manifest, content, etc.), which I'm not sure how to combine their suggestions with my code as it is in C#.
What am I missing here?
Any help will be much appreciated.
Thanks!!!
I am still waiting for anyone who could help. My question is very detailed and well explained. So is the code, that can be easily pasted, as is, to the editor (Just have the relevant refereces and the CRX file in your machine). If I can narrow it to one sentence, it would be: "How do I use the Selenium IDE API from the web driver in C# code?"

Javascript not working with Selenide and PhantomJS

I'm working on a project in IntelliJ that uses PhantomJS and Selenide to automate web browsing activity. To run Javascript commands, we use the executeJavascript() method in our Java code.
We call this method many times in our code to execute the Javascript commands that we want.
For this particular case, we are making a program that should automatically log us into Footlocker.
Code for program:
public Boolean doInBackground() {
WebDriver driver = getWebDriver();
System.out.println("Running Footlocker");
open(account.getEarlyLink()); //opens URL
System.out.println("Running Footlocker");
if (!loggedIn) {
WebDriverRunner.setWebDriver(driver);
$("#guest_welcome_login").shouldBe(visible).click();
$("#login_container").shouldBe(visible);
}
executeJavaScript("$('html').find('iframe').eq(1).contents().find('#login_email').val('%s')", account.getUsername());
executeJavaScript(String.format("$('html').find('iframe').eq(1).contents().find('#login_password').val('%s')", account.getPassword()));
executeJavaScript("$('html').find('iframe').eq(1).contents().find('button.button.cta_button').click()");
$("#member_welcome").shouldBe(visible);
}
When we run the program, none of the executeJavascript() commands are actually executed, but when we run each command one by one in the IntelliJ expression executer (in the debugger), they work.
Anyone know what's happening here?
Did you try to SWITCH into frame?
Typically in Selenium you need to switch into frame/iframe to get access to its elements. Like this:
switchTo(frame(1));
executeJavaScript("$('#login_email').val('%s')", account.getUsername());

Can I/how can I translate a Selenium webdriver test script from node.js over to phantomjs - ghostdriver?

I recently began working with Selenium and to make life easier to start I was using node to run my scripts so that I could visually monitor the tests. My challenge now is to convert it so that it can be run as a headless test. Unfortunately, most of the resources that I have come across only address using phantomjs and ghostdriver with Java or Python. My boss wants me to run the test through phantomjs without Java or Python. Eventually these tests will be run remotely through a Linux VM on a server without a GUI. Currently I am testing using Mac OS X 10.8 and still have many bridges to cross in order to get to my goal.
My most important question firstly, is it possible to run a script from phantomjs through a port without the use of Java or Python? I have spent hours poring through as many resources as I could come across and I've come up with no solution.
If so, how can I properly initialize the test to run headless? Here is how I scripted the start of my functioning test. I want to properly switch the capabilities from firefox to phantomjs and be able to run it headless using the appropriate port. The rest of the test navigates to a specific site, logs in through a widget, then does further navigation to the area which I will build further tests on which to manipulate after I get this working.
var webdriver = require('selenium-webdriver'),
SeleniumServer = require('selenium-webdriver/remote').SeleniumServer;
var server = new SeleniumServer("Path/selenium-server-standalone-2.39.0.jar", {
port: 8910
});
server.start();
var driver = new webdriver.Builder().
usingServer(server.address()).
withCapabilities(webdriver.Capabilities.firefox()).
build();
The test works perfectly, but I am new to this so there might be something foolish that I am overlooking. Please let me know what adjustments to make so that it will run headless through phantom. When I attempt to use node to run the script after switching capabilities to phantomjs it produces
"/Selenium/node_modules/selenium-webdriver/phantomjs.js:22
LogLevel = webdriver.logging.LevelName,
^
TypeError: Cannot read property 'LevelName' of undefined
at Object.<anonymous> (/Selenium/node_modules/selenium-webdriver/phantomjs.js:22:33)
That's a read only file that I can't adjust, any attempts that I made to define "LogLevel" or "LevelName" to the appropriate corresponding value (DEBUG, etc.) were fruitless.
And if I run it through phantomjs itself I get -
"Error: Cannot find module 'path'
phantomjs://bootstrap.js:289
phantomjs://bootstrap.js:254 in require"
(It also lists module 'http') -- (and various undefined function errors)
I feel that with that instance I didn't properly organize where the files for Selenium, phantomjs, and ghostdriver should go in order to play nice. I also removed the server setup portion and instead ran this first, then the script separately.
phantomjs --webdriver=8910
But it yielded the same result. All of my research to fix these issues turned up instructions for Java and Python but not Javascript by itself. Rather than chase through many rabbit holes I figured it wise to consult better minds.
If you know better than I do and that it is fruitless to attempt this without Java or Python, please let me know. If you know where the issue lies within my script and could propose a fix please let me know. I hope that I have properly described the nature of my issue and if you need more information I will do my best to provide it to you.
This is my second week working with Javascript so if you believe I am making a noob error you very well may be correct. Please, keep in mind that the script works through node with selenium webdriver.
Many thanks for your time!!!
~Isaac
This was a bit tricky but here is the solution I've pieced together:
var webdriver = require('selenium-webdriver'),
SeleniumServer = require('selenium-webdriver/remote').SeleniumServer,
server = new SeleniumServer('/path/to/selenium/selenium-server-standalone-2.41.0.jar', {
port: 4444
}),
capabilities = webdriver.Capabilities.phantomjs();
capabilities.set('phantomjs.binary.path', 'path/to/phantom/bin/phantomjs');
var promise = server.start().then(function() {
var client = new webdriver.Builder().
usingServer(server.address()).withCapabilities(
capabilities
).build();
return {
'client': client,
'server': server
};
}, function(err) {
console.log('error starting server', err);
});
You can then use the promise with selenium's mocha-compatible test framework to hold the test till the server has started.
I found the documentation really helpful once i figured out the navigation is on the far right of the page. Here's the URL: http://selenium.googlecode.com/git/docs/api/javascript/module_selenium-webdriver.html
Then you'll be stuck where I am. Getting selenium-webdriver to quiet down.

How to open a URL with a hash using Selenium?

I'm trying to test my Backbone.js web application with Selenium IDE.
Selenium can open my test case's initial URL so long as it's in a fresh browser window -- e.g. open /#/login -- but it times out whenever it tries to open subsequent URLs.
It seems that Selenium is listening for an event that just isn't triggered when only the URL hash changes.
I would imagine this happens any time you're using hashchange + Selenium...
In Selenium IDE simply use the 'storeEval' command, for example :
Command = storeEval
Target = window.location.hash='/search/events/birthdays/1'
storeEval runs the javascript snippet assigned to "target".
What you can then do, is have one test case that opens the start page using the open(url) command, and the rest of your cases changing the hash using the storeEval command.
Run this on console of developer tool -> window.location.hash='#abcde'. It should change hash for you in the browser tab.
Execute javascript through Selenium Webdriver and Java:
((JavascriptExecutor) driver).executeScript("window.location.hash='#abcde'");
A brief update: We gave up trying to use Selenium IDE to write our integration tests, and instead used the Selenium Python bindings for Selenium WebDriver.
With this approach, we can navigate to a URL and then use WebDriverWait to detect a particular change in the DOM, e.g.
driver = webdriver.Firefox()
driver.get("/#/login")
WebDriverWait(driver, 10).until(
lambda driver: driver.find_element_by_css_selector("form.login").is_displayed())

Categories

Resources