Handling Browser Authentication using Selenium - authentication

Does anyone know about handling Browser Authentication using Selenium or any other tool during automation?

EDIT in 2015:
This answer is outdated. WebDriver nowadays supports authentication! See How to handle authentication popup with Selenium WebDriver using Java
Original answer:
This is not handled very well by Selenium.
You can try using http://username:password#example.com/yourpage
instead of just http://example.com/yourpage
However, as far as I know, Firefox will still pop up a browser dialog requesting a confirmation.
You can try Robot if you're using Java (or any similar tool like AutoIt).
You could use driver.manage().addCookie() if you're using WebDriver.
Or a custom FirefoxProfile that has already passed the authentication once.

I spent days on this - literally.
Trying to get past browser level authentication within my company network to hit an application.
The solution was to use the 'unsername:password#' component within the URL, BUT to add a forward slash at the end of the login URL.
So total login URL looks like this (note the '/' after yourpage):
http://username:password#example.com/yourpage/
Works with Watir, Capybara and Selenium Webdriver.

Everything I have read on the Web didn't help me. So before making a request, like this:
driver.get(url);
you have to run a new thread like this:
RunScript runScript = new RunScript();
runScript.start();
In this case you are free to input login and password on another thread of follwing class
public class RunScript extends Thread {
#Override
public void run() {
try {
File file = new File("D:\\jacob-1.18-x86.dll");
System.setProperty(LibraryLoader.JACOB_DLL_PATH, file.getAbsolutePath());
AutoItX autoIt = new AutoItX();
Thread.sleep(2000);
autoIt.winActivate("yourWindowName", "");
autoIt.winWaitActive("yourWindowName");
if (autoIt.winExists("yourWindowName")) {
autoIt.send("username{TAB}", false);
autoIt.send("password{Enter}", false);
}
}
} catch (InterruptedException ex) {
//
}
}
}

All the hacks via auto-it, sikuli, etc. just wasting your time when you'll run it in your CI solution, using several browser types / OS / Version / Resolutions etc.
The way to do it correctly is to identify the authentication actual method and perform a login using Rest protocol for instance.
I used it to get the JSESIONID cookie and insert it to the selenium driver.
hint on that: go to a non-exiting url of the domian first, then set the cookie, then go to the required url - you are logged-in.
use: rest client authentication to get the JSESSION ID
and With this information:
browser().navigate(foo.getUrl()+"non-exiting-url");
//the information got from the rest client login:
Cookie cookie = new Cookie(name, value, domain, path, expiry, isSecure, isHttpOnly);
try {
driver.manage().addCookie(cookie);
} catch (Exception e) {
System.out.println(e.toString());
}
browser().navigate(foo.getUrl());

you can use auto IT script to handle this problem
WinWaitActive("[CLASS:Chrome_WidgetWin_1]", "", time)
Send("user")
Send("{TAB}")
Send("pass")
Send("{ENTER}")

with Chrome 70 and other versions :
http://username:password#example.com/yourpage

You can use Java Robot class with Selenium 2 /Selenium WebDriver using Firefox
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:9990");
WebElement myDynamicElement = driver.findElement(By.id("app"));
Alert alert = driver.switchTo().alert();
try {
Robot robot = new Robot();
alert.sendKeys("username");
robot.keyPress(KeyEvent.VK_TAB);//go to password feild
robot.keyPress(KeyEvent.VK_P);
robot.keyPress(KeyEvent.VK_A);
robot.keyPress(KeyEvent.VK_S);
robot.keyPress(KeyEvent.VK_S);
robot.keyPress(KeyEvent.VK_ENTER);
} catch (AWTException e) {
e.printStackTrace();
}
}
Using Selenium with Robot
http://docs.oracle.com/javase/1.5.0/docs/api/java/awt/Robot.html

Related

Selenium getting stuck on data:, (MS Edge)

I want to use Selenium to navigate to a website. Selenium opens up the browser but does not navigate further to the specified website URL, but gets stuck on the "data:," url. After some time time I get the following exception:
"The HTTP request to the remote WebDriver server for URL http://localhost:58504/session timed out after 60 seconds"
Note: I did not specify the 58504 port anymore, so I guess it is the default port that Selenium use?
I am programming in C# and using the following Nuget Packages:
https://www.nuget.org/packages/Selenium.WebDriver/4.1.1
https://www.nuget.org/packages/WebDriverManager/2.13.0
Here is the code:
using OpenQA.Selenium;
using OpenQA.Selenium.Edge;
using WebDriverManager;
using WebDriverManager.DriverConfigs.Impl;
using WebDriverManager.Helpers;
public void VisitWebsite()
{
IWebDriver driver = null;
try
{
new DriverManager().SetUpDriver(new EdgeConfig(), VersionResolveStrategy.MatchingBrowser);
EdgeOptions options = new EdgeOptions();
options.AddArgument("--no-sandbox);
options.AddArgument("--disable-infobars");
options.AddArgument("--disable-dev-shm-usage");
options.AddArgument("--disable-browser-side-navigation");
options.AddArgument("--disable-extensions");
options.AddArgument("--dns-prefetch-disable");
options.AddArgument("--disable-gpu");
options.AddArgument("--disable-software-rastersizer");
driver = new EdgeDriver(options);
}
catch (Exception ex)
{
throw ex;
}
driver.Navigate().GoToUrl("https://www.google.com");
}
Where does it go wrong? Thanks!
I found the answer. It seems the DeveloperToolsAvailability policy for the MSEdge browser had a value that "blocks" Selenium from working. You can read more about it here: https://learn.microsoft.com/en-us/microsoft-edge/webdriver-chromium/?tabs=c-sharp#developer-tools-availability-policy

Link Click using selenium webdriver is giving timeout error, link is working fine on browser otherwise

I'm trying to write a piece of code using Testng in selenium, the problem is when i try to click a link, the code becomes unresponsive and gives error- Timed out receiving message from renderer
Tried driver.get("https://infostore.saiglobal.com/") instead of driver.findElement(By.linkText("Infostore")).click(); still remains unresponsive - Doesnot get directed to the webpage - https://infostore.saiglobal.com/
#Test
public void testSai() throws Exception {
driver.get("https://www.saiglobal.com/"); //open homepage
driver.findElement(By.id("CybotCookiebotDialogBodyButtonAccept")).click(); //accept cookie
driver.findElement(By.cssSelector("#sai-header > div > div.main-nav > div.store-box > div")).click(); //click on Login to open list
sleep(2);
driver.findElement(By.linkText("Infostore")).click(); //click on infostore to be redirected to https://infostore.saiglobal.com/
System.out.println(driver.getCurrentUrl());
Yes I have checked this issue and there is an workaround for this issue if you wish to have this.Try following code.
Take the href attribute value from the link element.
Delete all cookies.
driver.navigate().to(URL);
public static void main(String[] args){
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir") + File.separator + "\\Executables\\Chromedriver.exe");
WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, 5);
Actions actions = new Actions(driver);
driver.get("https://www.saiglobal.com/");
driver.findElement(By.id("CybotCookiebotDialogBodyButtonAccept")).click();
WebElement element=wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[#class='desktop-login']")));
actions.moveToElement(element).build().perform();
WebElement element1=wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[#class='desktop-login']/ul/li/a[contains(text(),'Infostore')]")));
String str1=element1.getAttribute("href");
driver.manage().deleteAllCookies();
driver.navigate().to(str1);
System.out.println(driver.getCurrentUrl());
}
This seems to be an error with Selenium that the developers have been dealing with for over a year. They never really give a concrete answer as to what causes it or how to fix it.
The first port of call would be to make sure that your browser and Selenium are compatible. Try opening a different URL that you know works, and if the error persists then there is likely an error with the compatibility of your selenium and web browser. If it works, then there is something wrong with your website.
For reference, I opened your website using Python Selenium, and had no issues loading or interacting with elements. So the error is local to the software you are using.
The issue can also be caused by sleeps(no idea why), so try removing any sleeps and see if this stops the issue.

Create Selenium Webdriver once and use in Cucumber's all steps

I've experience in Back-End automation testing, but I'm new to Front-End.
I've created BDD format tests for a website and now I want to automate it.
I decided to use Selenium + cucumber using Maven for desktop versions of website.
Now let's start:
For example my feature file looks something like this:
Feature: User change password page
Scenario: User doesn't provide passwords
Given user is logged in
And user is on change password page
When user clicks SAVE button
Then website should notify that password fields are mandatory
Scenario: User types wrong current password
Given user is logged in
And user is on change password page
When user provides invalid current password
And user clicks on save button
Then website should notify user that current password is invalid
At first I thought it would be good that I log in the system only for first scenario. (in this example in second scenario I already would be logged in).
But as I saw it's not good approach. So I open and close browser for each scenario using the code:
#Before
public void beforeScenario(){
driver.get("https://example.com");
}
#after
public void afterScenario(){
driver.close();
}
That's OK for me. But I don't want to create WebDriver for each scenario and I don't want to initialize my POM objects for each scenario.
Now my Before method looks like it:
WebDriver driver;
HomePage home;
LoginPage login;
RegistrationPage reg;
#Before
public void beforeScenario(){
driver = new ChromeDriver();
home = new HomePage();
login = new LoginPage();
reg = new RegistrationPage();
}
I want to initialize these objects before steps are run and use them in every step.
I research and found out that cucumber-JVM doesn't support #beforeAll hook.
Also I don't want to do some manipulation like:
if( firstTime) {
//initialise everythin
firstTime = false
} else {
//do nothing
}
How can I achieve that? Where can I initialize everything I want before my tests start?

SafarDriver Selenium Page title is incorrect after loading new page

I have a Selenium 2 test that uses a login form and then asserts that the login has succeeded by verifying the page title has changed.
The test is written in Java/JUnit, WebDriver and Fluent Selenium
fwd.title().within(secs(5)).shouldContain(partialTitle);
The tests work on Firefox and Chrome.
On Safari the page title is still the old login page title.
The screencast we have generated shows that the URL after a successful login has changed, but the title hasn't.
I think the SafariDriver is not waiting for the page load event to complete before the assertion.
I have the same issue!!!
My test fail because title is used for checking test "Step".
With Firefox and Chrome no problem; with Safari it's a problem!!!
I found this "hack" that work, but it's necessary to manually check the title after each "click":
def static void waitForPage(driver, String title) {
//Hack to make login working on Safari&IE
(new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
return d.getTitle().startsWith(title);
}
});
}
I use GEB + SPOCK and with safari driver there is a "know issue" about implicit/explicit wait (ref. https://code.google.com/p/selenium/issues/detail?id=5860).
So, a nice workaround for make test runnable on Safari browser is to wait for page title:
static at = {
waitFor { title == "Homepage" }
}
This will force the driver to wait until title change (the timeout is configurable).

Selenium IDE: Verify broken link 404 not found?

Any one have any idea whether Selenium IDE able to verify any broken link in page??
Short answer: yes, but probably not the best idea.
Selenium might not be the best program to do this - especially if you use only Selenium IDE.
Multiple programs exist with the sole purpose of testing broken links (do a little search), hell, even the W3C has a webapp for that.
That said, you could take the output from Selenium IDE formatted to your favourite language, program a Selenium test case with more advanced Unit Testing classes, include a while loop which would check for the existence of more links, and visit them / check headers, if you really want to do this through Selenium.
In short, you can't (yet). See a more full writeup of the situation at: How do I ask Selenium IDE to check a HTTP Status Code (e.g. 2XX, 404, 500)
Basically the selenium maintainers decided this function did not belong in selenium because error codes are read by machines not humans.
This sounds like a job for a simple spider script, for example using the wget on Linux
--spider
When invoked with this option, Wget will behave as a Web spider,
which means that it will not download the pages, just check that
they are there. For example, you can use Wget to check your book‐
marks:
wget --spider --force-html -i bookmarks.html
This feature needs much more work for Wget to get close to the
functionality of real web spiders.
You can use 404 status code to verify using REST web services.
Use gson and apache jars to get it.
public class Testing{
public static void main(String[] args) {
try{
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.navigate().to("https://www.amazon.in/");
List<WebElement> links = driver.findElements(By.tagName("a"));
System.out.println("Number of links : " + links.size());
for(WebElement e : links) {
String linkText = e.getAttribute("href");
System.out.println("Link -->>" +linkText);
if(linkText!=null && !linkText.isEmpty()) {
HttpPost post = new HttpPost(linkText);
HttpClient client = HttpClientBuilder.create().build();
HttpResponse res = client.execute(post);
String s = res.getStatusLine().toString();
if(s.contains("404")) {
System.out.println("Navigated");
//your code to handle logic
} else {
//your code to handle logic with other response code
}
}
}
} catch (Exception e) {
System.out.println(e.getStackTrace());
}
}
}