How to Handle Authentication alert of browser in selenium webdriver? - selenium

Can anyone know that how can we handle Authenticate alert box of browser in selenium Webdriver ?
I user following code but its not working.
driver.switchTo().alert().authenticateUsing(new UserAndPassword("uname", "Password"));
Here is a screenshot of what I am trying to fill in:
Does anyone know how can I enter those credentials?

You can handle this in two ways:
You can pass the username and password directly through the URL like this:
driver..get("https://MyUserName:password#staging.www.abc.com")
You can also use AutoIT Tool for handling any kind of window popups.
For this you first have to download and install AutoIt
Then download SciTE4AutoIt3
You can do scripting in it, or you can use Au3Recorder. It is not available in new versions of SciTE, but you can download it from old versions separately. Unzip it and copy:
autoit-v3.3.14.0.zip\install\Extras\Au3Record
to
[#Install Dir of AutoIt in Program files]\Extras\Au3Record
Now you can start the recorder directly by clicking Au3Record.exe or you can find it in the Script Editor window Tools >AU3Recorder.
For it you have to create a blank .au3 file in the Script Editor. Now start recording. Perform action on Window Popup. Stop when Done. Save it with .au3 format.
Now GO to Saved File location >> Right Click on the File and compile it (Compile Script(x64) or else). It will create an .exe file in the same folder.Now run that script in your Project using:
Runtime.getRuntime().exec("File Loaction/MyAutoItScript.exe");
It will work.

Try below code:
String username = "myUsername";
String password = "myPassword";
String URL = "http://" + username + ":" + password + "#" + sso.mywebsite.com/usdf/ls/dia?kkkk;
driver.get(URL); // Basically operation done here itself still if not work use further Alert code as well
Alert alert = driver.switchTo().alert();
alert.accept();
Full code will be like:
driver.get("https://sso.mywebsite.com/usdf/ls/dia?kkkk");
String url = driver.getCurrentUrl().replaceAll("https://", "");
String username = "myUsername";
String password = "myPassword";
String URL = "https://" + username + ":" + password + "#" + url;
driver.get(URL); // Basically operation done here itself still if not work use further Alert code as well
Alert alert = driver.switchTo().alert();
alert.accept();
Note : Even alert code do not required .. use it as it works for you and this code works on chrome better

Something like this?
driver.Navigate().to("http://UserName:Password#url.‌​com")
or
WebDriverWait wait = new WebDriverWait(driver, 10);
Alert alert = wait.until(ExpectedConditions.alertIsPresent());
alert.authenticateUsing(new UserAndPassword(*username*, *password*));

I use Java for my test automation. I have searched for a decent way to deal with these sign in pop ups and cannot find one. The most common answers are either to include in a URL as prefix prior to the real url (eg https:\username:password#www.website.com) or to use a wait for alert. These have not worked for me as: on a form submit there is no simple url to use and I am not sure as to the security including the password in the start of the url; with the wait for alert the webdriver hangs until there is a response - which only comes from submitting the login response via the pop up.
The workaround I have found is poor - I've not got it to work in a headless environment and so limits this answers usefulness. Would be great to get a real answer here. Note that I am running this in a Windows environment and if I was using Linux I have read that I could use xvfb to provide a 'screen' for sikuli and then this would work - if anyone can comment on how to do this on a Windows server that would be MUCH appreciated.
I use Sikuli for the automation of things I cannot automate via Selenium. Sikuli does many things, including letting you basically feed it images that it performs actions on.
For this purpose I run Sikuli on a thread started prior to clickin the submit that leads to the sign in pop-up. As it is running on a different thread it doesn't block the main thread, so it can still execute the log in. Once it logs in it shuts down and logging in closes the pop up and reactivates the main thread.
Specifically:
Sikuli MAVEN entry for POM:
<dependency>
<groupId>com.sikulix</groupId>
<artifactId>sikulixapi</artifactId>
<version>1.1.4-20191010.160947-268</version>
</dependency>
In the main code use a runnable executed via an executor:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
private final AtomicInteger expectedResultCount;
private final AtomicInteger publishedResultCount;
private final ExecutorService executor;
ExecutorService executor = Executors.newFixedThreadPool(5);
String processName = "asic-login";
LoginPopUp login = new LoginPopUp(this, processName);
addResultExpectation(processName);
executor.execute(login);
The runnable here implements an interface I use to keep things tidy:
The main class implements the interface to manage the threads:
public class TestRunner implements ResultPublisher{
These are functions inside the main class for thread management:
private void addResultExpectation(String process){
resultMap.put(process, new JSONObject());
expectedResultCount.addAndGet(1);
}
public void publishResult(JSONObject result){
String process = result.getString("process-name");
String strResult = result.getString("result");
resultMap.put(process, result);
publishedResultCount.addAndGet(1);
if(publishedResultCount.get() == expectedResultCount.get()){
executor.shutdown();
System.out.println("shutting down executor for run " + runId);
}
}
This is the interface
import org.json.JSONObject;
public interface ResultPublisher {
void publishResult(JSONObject result);
}
This is the runnable Runnable - an inner class in the TestRunner main class:
private class LoginPopUp implements Runnable{
private ResultPublisher publisher;
private String filePath;
private String processName;
private LoginPopUp(){
}
public LoginPopUp(ResultPublisher publisher, String processName){
this.publisher = publisher;
this.processName = processName;
}
private void publish(JSONObject result){
publisher.publishResult(result);
}
public void run(){
JSONObject result = new JSONObject();
result.put("path", filePath);
try{
Screen sd = new Screen();
ScreenUtility s = new ScreenUtility(imagesDirectory);
s.clickImage("LoginTitle.PNG", 10, 2500);
s.typeImageWithOffset("UserName.PNG", userName, 30,0);
s.typeImageWithOffset("Password.PNG",String.valueOf(password), 50,0);
s.clickImage("AsicSignIn.PNG", 10, 250);
}catch(Exception ex){
result.put("result", ex.getMessage());
result.put("process-name", processName);
publish(result);
Logger.getLogger(BCSRobot.class.getName()).log(Level.SEVERE, null, ex);
return;
}
result.put("result", "logged in successfully");
result.put("process-name", processName);
publish(result);
return;
}
}

Related

How to understand if credentials are valid or not using selenium

I created an app that lets users login through my app to Wikipedia, and I achieved this goal with selenium, but I can't find a way to verify either credentials are ok or not.
I tried find by id but since failed condition doesn't display an ID it's not helping.
private void button1_Click(object sender, EventArgs e)
{
string BaseUrl = "https://en.wikipedia.org/w/index.php?title=Special:UserLogin&returnto=Main+Page";
int TimeOut = 30;
var driver = new FirefoxDriver();
driver.Navigate().GoToUrl(BaseUrl);
var loginBox = driver.FindElement(By.Id("wpName1"));
loginBox.SendKeys("email.address#gmail.com");
var pwBox = driver.FindElement(By.Id("wpPassword1"));
pwBox.SendKeys("!SuperSecretpassw0rd");
I would like to know if entered credentials are correct or not.
A general approach to this kind of question is to ask yourself, "How can a human see this?" and then replicate this behavior in your test. In your example, how would a human detect that the login is wrong?
A human would see the error message.
Selenium on the other hand only sees the DOM tree. So for Selenium to see the error message, you need to find out where to look in the DOM tree. To do this, open your browser developer tools and find the matching section in the DOM tree:
With this in mind, a very simple solution is to find the error div that is shown when the credentials are invalid.
var error = driver.findElement(By.className("error"));
Then you can check if the element actually exists and you can use additional Selenium methods to inspect the actual contents of the error message, to see what the error is. If the field is not present then you could assume that the login succeeded. In addition you can use driver.getCurrentUrl() to inspect whether you are still located on the login page, to confirm that you are really logged in.
That being said, if you try to do any serious browser testing you should consider using the page object model (see https://www.toolsqa.com/selenium-webdriver/page-object-model/) so you don't end up with an unmaintainable mess of test cases.
As you havn't mentioned the language binding this solution is based on Java.
An elegant approach to validate whether the credentials are valid or not would be to induce a try-catch{} block to look for the element with the error inducing WebDriverWait for the desired visibilityOfElementLocated() and you can use the following Locator Strategies:
Code Block:
public class A_demo
{
public static void main(String[] args) throws Exception
{
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("start-maximized");
options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
options.setExperimentalOption("useAutomationExtension", false);
WebDriver driver = new ChromeDriver(options);
driver.get("https://en.wikipedia.org/w/index.php?title=Special:UserLogin&returnto=Main+Page");
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("input[name='wpName']"))).sendKeys("Helios.Lucifer#stackoverflow.com");
driver.findElement(By.cssSelector("input[name='wpPassword']")).sendKeys("!SuperSecretpassw0rd");
driver.findElement(By.cssSelector("button#wpLoginAttempt")).click();
try
{
new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("form[name='userlogin']>div.error>p")));
System.out.println("Unsuccessful login attempt");
}
catch (TimeoutException e)
{
System.out.println("Successful Login.");
}
driver.quit();
}
}
Console Output;
Unsuccessful login attempt

Open verification code sent in mail box then copy this code and paste it into verification code field in selenium testing

I am new to selenium web testing i have automated a Sign-In process for a web base application. now making it for Sign Up process i am stuck at a point where a verification code is sent to a mail address and then i have to copy that into my verification code field and proceed further
As i have searched so far i came to know about the mailosaur server but unable to copy that email verification code into my automated web browser. i also searched for the tutorials but unable to find any useful resource. also i want to generate random emails that part is also not getting in my mind.
As i am new to selenium so it is requested to please provide detail answer so i can understand it better, Thanks in advance, working on Intellij, Mavaen (Java)
You can use mailinator.com. No need to register or create a mail box. In your app just enter email with made up name #mailinator.com (asad1#mailinator.com, asadXY#mailinator.com, whatever).
To collect confirmation link (double opt in) I'm using this:
public class Mailinator {
public WebDriver driver;
public Mailinator(WebDriver driver) {this.driver = driver;}
public String urlMailinator = "https://www.mailinator.com/";
public WebDriverWait waitSec(WebDriver driver, int sec) {return new WebDriverWait(driver, sec);}
public static String doubleOptInLink = null;
public String getDoubleOptInLink() {return doubleOptInLink;}
public void setDoubleOptInLink (String doubleOptInLink) {Mailinator.doubleOptInLink = doubleOptInLink;}
public void collectDoubleOptInLink(String userEmail, int expectedNumberOfDeliveredEmails) throws InterruptedException {
driver.get(urlMailinator);
WebElement fldInbox = waitSec(driver, 5).until(ExpectedConditions.elementToBeClickable(By.id("inboxfield")));
fldInbox.sendKeys(userEmail);
WebElement btnGo = driver.findElement(By.xpath("/html/body/section[1]/div/div[3]/div[2]/div[2]/div[1]/span/button"));
btnGo.click();
waitSec(driver, 600).until(ExpectedConditions.numberOfElementsToBe((By.xpath("//*[#id=\"inboxpane\"]/div/div/div/table/tbody/tr")), expectedNumberOfDeliveredEmails));
WebElement lastMailLink = driver.findElement(By.xpath("//*[#id=\"inboxpane\"]/div/div/div/table/tbody/tr"));
lastMailLink.click();
Thread.sleep(3000);
driver.switchTo().frame(driver.findElement(By.id("msg_body")));
setDoubleOptInLink(driver.findElement(By.xpath("//*[#id=\"intro\"]/tbody/tr/td/a")).getAttribute("href"));
}
}
In my scenario:
register to webapp with new made up email, confirmation email is send
using collectDoubleOptInLink(email, 1); is the confirmation link set as doubleOptInLink
calling another method to go to the confirmation link with getDoubleOptInLink();
Sure you will need change what string comes to setDoubleOptInLink();
In specific cases don't forget to setDoubleOptInLink(null);.

Can "driver.findElement" be used as method and be called in a program

I am using "driver.findElement" multiple times. So can it be saved in a method and called multiple times?
driver.findElement(By.xpath("//tbody[#id='detailsstockid']/tr/td[12]/a/input")).click();
driver.findElement(By.id("supplier_name")).click();
driver.findElement(By.xpath("//select[#id='supplier_name']/option[7]")).click();
driver.findElement(By.id("catagory_name")).click();
driver.findElement(By.id("productname")).sendKeys("AutoProductNew");
driver.findElement(By.id("productcode")).sendKeys("ap02");
You just need a wrapper like this
public static WebElement findElement(By locator){
WebElement anElement = driver.findElement(locator);
return anElement;
}
findElement(By.id("id")).click();
Basically you can call whatever method available to the object
I think what you are trying to do is to simplify your code... maybe make it more human readable. This is a noble goal but I would suggest that you take a different approach. Without more info, I don't know what your typical script is like. From the example code you provided, I would assume that you are going to a few pages, clicking on things, filling in textboxes, etc. I would suggest that you look into the page object model.
There are a LOT of references on the web on this topic, here's a good one to start with.
http://www.seleniumhq.org/docs/06_test_design_considerations.jsp#page-object-design-pattern
The basic concept is create one Class file per page. [Page doesn't always literally mean an entire page. For example, I would create a separate page object for each popup dialog.] What this allows you to do is to consolidate all the code specific to that page into a single location. If you know what an API is and understand it, you will basically create an API for each page/dialog you touch. If done properly, it will greatly simplify and organize your code and will make creating new scripts drastically easier and they will be much easier to read. The benefits are numerous... one big one is code maintenance is made SO much easier. Imagine you have 100 scripts that all start by logging into the site. Let's assume the design of the login page changes... without the page object model, you will have to update all 100 scripts individually. If you are using the page object model, you open the LoginPage.java class, make the change to the Login() method, and you just fixed all 100 scripts.
You may be asking... how does this answer my question? What it does is turns
driver.findElement(By.id("supplier_name")).click();
into
somePage.clickSupplierName();
in your actual script. I think this is more along the lines of what you are asking without answering your specific question. The .findElement code still exists, but is "hidden away" in the page object.
A simple example. I wrote a script, with supporting page objects, to navigate to Amazon.com, search for Star Wars, return the # of found items, and then navigate to the Today's Deals page. The entire code is below.
program.java (Main script)
public class program
{
public static void main(String[] args)
{
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("https://www.amazon.com");
// HOME PAGE
HomePage homepage = new HomePage(driver);
homepage.search("star wars");
// SEARCH RESULTS PAGE
SearchResultsPage searchResultsPage = new SearchResultsPage(driver);
System.out.println(searchResultsPage.getNumberOfResults());
// navigate to the Today's Deals page
searchResultsPage.clickTodaysDealsLink();
// TODAY'S DEALS PAGE
// do more stuff
driver.close();
driver.quit();
System.out.println("Done");
}
}
HomePage.java (Home page page object)
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class HomePage
{
WebDriver driver;
private By searchTextboxLocator = By.id("twotabsearchtextbox");
public HomePage(WebDriver driver)
{
this.driver = driver;
}
public void search(String searchString)
{
driver.findElement(searchTextboxLocator).sendKeys(searchString + "\n");
}
}
SearchResultsPage.java (Search results page page object)
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class SearchResultsPage
{
WebDriver driver;
private By todaysDealsLinkLocator = By.linkText("Today's Deals");
private By numberOfResultsLocator = By.id("s-result-count");
public SearchResultsPage(WebDriver driver)
{
this.driver = driver;
}
public String getNumberOfResults()
{
// grabs only the total count of search results from the string in the form "1-16 of 7,488,146 results for "
return driver.findElement(numberOfResultsLocator).getText().split(" ")[2];
}
public void clickTodaysDealsLink()
{
driver.findElement(todaysDealsLinkLocator).click();
}
}

how effectively i can use ui automation recorded test cases for other releases of the application

I've web application, I want recorded test cases and play back that cases.
1st release of the application, I've login module which has user name and password and recorded 500 test cases for entire application. Among 500 test cases 200 test cases are using logging by username and password.
2nd release of the application, I've login module which has only username, so I want use previous recorded test cases by modifications not like go to all the test cases change the password field. Here I'm having some requirements for the testing framework
Can I get what are test cases will effect by changing field like in above example?
Is there any way to update in simple, not going like in all the files and changing
I've used different UI Automation testing tools and record & Play back options are very nice, but I could not find the way I want in the UI Automation test framework.
Is there any Framework available which does the job for me?
Thanks in advance.
This is a prime example of why you never should record a selenium test case. Whenever you want to update something like login you have to change them all.
What you should do is create a test harness/framework for your application.
1.Start with creating a class for each webpage with 1 function for each element you want to be able to reach.
public By username(){
return By.cssSelector("input[id$='username']"); }
2.Create helper classes where you create sequences which you use often.
public void login(String username, String password){
items.username().sendkeys(username);
items.password().sendkeys(password);
}
3.In your common test setup add your login function
#BeforeMethod(alwaysRun = true)
public void setUp() {
helper.login("user","password");
}
This give you the opportunity to programmaticly create your test cases. So for example if you want to use the same test cases for a different login module where password element is not present it could be changed like this.
items.username().sendkeys(username);
if(isElementPresent(items.password())
items.password().sendkeys(password);
The function "isElementPresent" could look like this
public boolean isElementPresent(By locator){
try {
driver.findElement(locator);
logger.trace( "Element " + stripBy(locator) + " found");
} catch (NoSuchElementException e) {
logger.trace( "Element " + stripBy(locator) + " not found");
return false;
}
return true;
}

Websdriver - sendKeys command is not typing on Password type field

I am trying to learn selenium webdriver automation but I am finding that the sendKeys command is not typing on Password type fields. I can see that some other people are also experiencing the same problem by googling it, but I haven't seen any correct answer yet. Could anyone please help me here.
Please find below sample code; I generated code from Selenium IDE and its working fine on IDE but not when I use webdriver.
package com.example.tests;
public class Login {
private WebDriver driver;
private String baseUrl;
private boolean acceptNextAlert = true;
private StringBuffer verificationErrors = new StringBuffer();
#Before
public void setUp() throws Exception {
driver = new FirefoxDriver();
baseUrl = "http://www.webs.com/";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#Test
public void testLogin() throws Exception {
driver.get(baseUrl + "/");
driver.findElement(By.cssSelector("span")).click();
driver.findElement(By.id("FWloginUsername")).clear();
driver.findElement(By.id("FWloginUsername")).sendKeys("aug2qatestingqa#yahoo.com");
driver.findElement(By.id("FWloginPassword2")).clear();
driver.findElement(By.id("FWloginPassword2")).sendKeys("webs");
driver.findElement(By.id("sign_in_leaf")).click();
}
There were two password fields and one is hidden. Solution is to click on first password [hidden] field to get second password field enabled.
driver.findElement(By.id("FWloginUsername")).sendKeys("aug2qatestingqa#yahoo.com");
driver.findElement(By.id("FWloginPassword")).click();
driver.findElement(By.id("FWloginPassword2")).clear();
driver.findElement(By.id("FWloginPassword2")).sendKeys("webs");
I had almost a similar situation for Password field. There were two elements for the same 'Password' field but with different IDs. The JavaScript was toggling "type = password" on run time for a click, clear or any action to this field.
Solution in this case is to find the text with input type = password,
for example:
driver.FindElement(By.CssSelector("input[type='password']")).SendKeys(IWebElement);
My problem was that I used ActionChains which caused the later fields not being filled when using send_keys method.
The solution was to call actions.reset_actions()
e.g.
actions = ActionChains(driver)
actions.key_down(Keys.LEFT_CONTROL).send_keys("a").perform()
actions.key_down(Keys.LEFT_CONTROL).send_keys("c").perform()
actions.reset_actions()
# now send_keys() method works again
cvvTxtBox().sendKeys("1234");
cvvTxtBox().sendKeys(Keys.TAB);
Final Solution on this problem.
Else use Robot