UnhandledPromiseRejectionWarning: NoSuchSessionError: Tried to run command without establishing a connection - node.js

I was trying to use selenium-webdriver with nodeJs. Every thing was going smooth but as soon as it end it pop up with this error in terminal.What's wrong in this.
UnhandledPromiseRejectionWarning: NoSuchSessionError: Tried to run
command without establishing a connection.
Here is my code,
let webdriver = require('selenium-webdriver');
const { Builder, Key, until } = require('selenium-webdriver');
By = webdriver.By;
let driver = new webdriver.Builder().forBrowser('firefox').build();
driver.get('https://www.google.com/');
pause(2, ScraperExample);
function ScraperExample() {
console.log('Scrapping the Pagee...');
pause(3, QuitDriver);
}
function pause(Time, FuncName) {
setTimeout(FuncName, Time * 1000);
}
function QuitDriver() {
driver.close();
driver.quit();
console.log('The Driver is set to off...');
}

I found one of the solution for my own question, we can resolve it by using any one of this drive.close() or driver.quit() if both of going to be used than we will face issues.
function QuitDriver() {
driver.quit();
console.log('The Driver is set to off...');
}```

Related

Getting error while running selenium test in node.js

The code I am using to run the automated test for google search is below.
const webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;
const driver = new webdriver.Builder()
.forBrowser('chrome')
.build();
driver.get('http://www.google.com');
driver.findElement(By.name('q')).sendKeys('webdriver');
driver.sleep(10000).then(function() {
driver.findElement(By.name('q')).sendKeys(webdriver.Key.TAB);
});
driver.findElement(By.name('btnK')).click();
driver.sleep(20000).then(function() {
driver.getTitle().then(function(title) {
if(title === 'webdriver - Google Search') {
console.log('Test passed');
} else {
console.log('Test failed');
}
driver.quit();
});
});
and it is throwing an error which says that element is not interactable. I have added extra time delays for loading page successfully.
(node:32241) UnhandledPromiseRejectionWarning: ElementNotInteractableError: element not interactable
element not interactable is telling you that the element you are trying to click on - is just not clickable.
You have 2 ways to overcome this:
Find the child element of the element you are trying to click on or its parent element.
Force the element to be clicked by injecting JavaScript into it:
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("document.getElementsByName
('btnK')[0].click();");
You need to make a couple of adjustments as follows:
Remove the first occurance of findElement(By.name('q')) as you are already using the line of code later.
Modify the second occurance of findElement(By.name('q')) to send the text and Key.RETURN
Remove the line findElement(By.name('btnK')) as you are already using the line of code later.
Your effective line of code will be:
const driver = new webdriver.Builder()
.forBrowser('chrome')
.build();
driver.get('http://www.google.com');
driver.sleep(10000).then(function() {
driver.findElement(By.name('q')).sendKeys('webdriver' + Key.RETURN);
});
driver.sleep(20000).then(function() {
driver.getTitle().then(function(title) {
if(title === 'webdriver - Google Search') {
console.log('Test passed');
} else {
console.log('Test failed');
}
driver.quit();
});
});
Basically driver.findElement() return promise,
So it can be anywhere in your code, so basically you have sync your code
may be here:
:driver.findElement(By.name('q')).sendKeys('webdriver');
or:
driver.findElement(By.name('btnK')).click();
so you need to make your code sync. just put ==>
await driver.findElement(By.name('btnK')).click();
-> this method won't work. Because you do not know browser behaviour some time it is fast and sometimes slow so this won't help you, driver.sleep().
Better to use:
await driver.wait(until.elementedlocated(By.xpath("xpath"),5000));

What is the proper way to handle connecting and closing the MongoDB Client from NodeJS (not using Mongoose!)?

export const client = new MongoClient(
process.env.ATLAS_URI,
// TODO: Figure out what this is and why it's needed to turn off deprecation warning
{
useUnifiedTopology: true,
}
);
Following this guide and all make sense...but she is just doing one 'call' and then close().
I need to keep doing repeated calls:
export const getAllProducts = async () => {
try {
await client.connect();
const cursor = await client.db("products").collection("data").find();
return await cursor.toArray();
} catch (err) {
throw new Error(err);
} finally {
await client.close();
}
};
The first call is fine. After that: Error: MongoError: Topology is closed, please connect
I honestly don't quite understand what Topology means, but evidently it's the close() that's contributing to the issue.
It doesn't make sense that I set up new MongoClient and the ATLAS_URI does have the 'database name' in there...so why I have to connect specify that again?
Anyway, the main part of my ❓ stands: Do I just keep a separate process going and not close it? Do I start back with a whole new MongoClient each time? 😕
I'll just put a brief answer here incase anyone runs into this.
The Mongodb documentation for the Node.js driver will give you simple examples that include the client.connect()and client.close() methods just to give you a runnable example of making a simple call to the database but in a real server application you are just opening the connection to the client once during start up and typically only closing when the server application is being closed.
So in short: You don't need to open and close and connection everytime you want to perform some action on your database.

How to run selenium webdriver code once element is present

Everything I've seen over the past month of looking is outdated.
Here's my problem, I traverse through about 5 different pages on one website before I get to the data I need. I can't fire off a driver.get as the url stays the same for all 5 different pages.
Since Node.js is asynchronous it runs the code before the element is present. I realize I could use a timeout, but i'm running this code 100's of times so a timeout won't work.
Everyone online says to do this, but it's outdated and doesn't work:
driver.findElement(By.css('#gridsortlink')).then(function(webElement) {
webElement.isElementPresent(By.css('#gridsortlink'))
.then(function(found) { console.log(found); });
});
If you do know how to do this that'd be great as I've been looking for a month now for the solution.
Your tried attempt looks incorrect, you should try as below :-
var webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;
driver.wait(until.elementLocated(By.css('#gridsortlink')), 5 * 1000).then(function(found) {
console.log(found);
});
In place of webElement.isElementPresent try to use driver.isElementPresent
driver.findElement(By.css('#gridsortlink')).then(function(webElement) {
driver.isElementPresent(By.css('#gridsortlink'))
.then(function(found) { console.log(found); });
});
I don't have access to your application thats why I created a demo code for gmail where I am putting some wrong value in Email field and after some time I am getting an error message. and the output here is 'true'.
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().forBrowser('chrome').build();
var By = webdriver.By;
driver.get('http://gmail.com');
driver.findElement(By.id("Email")).then(function(emailText){
emailText.sendKeys("aaaaaaaaaaaaaaaaaaaaaaaaaadddddddddddd").then(function(){
driver.findElement(By.id("next")).then(function(submit){
submit.click().then(function(){
driver.isElementPresent(By.className("error-msg")).then(function(text){
console.log(text);
});
});
});
});
});
Java code:
if((driver.findElements(By.css('#gridsortlink')).size())==1)
{
system.out.println(executecode);
}
else
{
system.out.println(element is not exist in webpage);
}
You can check element is present or not.
driver.findElements(By.css('#gridsortlink')).size() this row returns to 0 or 1.
1 means - Element exists on webpage.
0 means - Element does not exist on webpage.
Try in your code.

Break in console.log?

I have an irksome problem in my node.js test code. Somewhere, something prints out an error message using console.log (i think). I am somewhat fastidious about clutter in my logs, so I trying to catch whatever it is. I am 100% sure that it's not in my code, it must be in some library we're using.
This brought me to an interesting question: is it possible to set a breakpoint in console.log? I'm working in WebStorm IDE and I'm running on node.js 4.4.3.
You could overwrite console.log with a custom version that breaks into the debugger:
var _log = console.log.bind(console);
// es6
console.log = (...args) => {
_log(...args);
debugger;
}
// es5
console.log = function() {
_log.apply(null, arguments);
debugger;
}
Here's a one-liner if you'd like to copy/paste into a browser console for a drive test (verified in Chrome 51, Safari 9.1, and Firefox 46):
var _log = console.log.bind(console); console.log = function() { _log.apply(null, arguments); debugger; }
you could try something like this.
process.on('uncaughtException', function(err) {
console.log('Threw Exception: ' + err.stack);
});

selenium-webdriver in nodejs sample not returning current title

I was working through the selenium web-driver example and it didn't work. Several months ago it worked just fine so I am wondering if I am doing something wrong or if the testing methods have changed.
var assert = require('assert'),
test = require('selenium-webdriver/testing'),
webdriver = require('selenium-webdriver');
var By = webdriver.By;
test.describe('Google Search', function() {
test.it('should work', function(done) {
var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();
driver.get("http://www.google.com");
driver.findElement(By.name("q")).sendKeys("webdriver");
driver.findElement(By.name("btnG")).click();
driver.getTitle().then(function(title) {
assert.equal("webdriver - Google Search", title);
done();
});
driver.quit();
});
});
The output is:
AssertionError: "webdriver - Google Search" == "Google"
Expected :"Google"
Actual :"webdriver - Google Search"
This tells me that the page has not updated yet but I am not sure why. The example appears here: https://code.google.com/p/selenium/wiki/WebDriverJs#Getting_Started
Selenium version from package.json: 2.39.0
Update
I should have also stated that the test is being run through Mocha. Is Mocha the culprit? When I tried this last time it was using Jasmine.
Straight from the example in the documentation, use wait:
driver.wait(function() {
return driver.getTitle().then(function(title) {
return title === 'webdriver - Google Search';
});
}, 1000);
Why do you need to use wait? Because the Google page works asynchronously. After you enter the keys, it may take a bit of time before the server sends a response and the page is updated.
You should also remove done. While in general you need it for asynchronous tests, it seems the sequencer that comes with this incarnation of Selenium's webdriver will block on quit until all actions are performed. This example in the documentation does not use it.
Also, if you wonder why there is no assertion: you'll know your test has failed if you get a timeout exception when the timeout has expired.

Resources