I'm writing automated tests for a website that uses pop-up authentication. I am able to provide the credentials by using the username:password#https://site.address.com formula, but in that case the Chrome window's title bar simply shows data;: and a blank page. After this, my tests will fail as the page is not really loaded and the elements can't be clicked.
If I don't provide credentials, then the title bar will show my URL, but I can't enter the credentials to enter the page, as the pop-up window has no elements I can refer to.
EDIT: when I try to send in the authentication data using driver.switchTo().alert() then the execution basically stops and I have to press cancel.
controller.getNavigator().goToPage(loginSiteAddress);
System.out.println(userName);
System.out.println(password);
controller.getNavigator().authenticate(userName, password);
public void authenticate(String userName, String password) {
driver.switchTo().alert().sendKeys(userName + Keys.TAB + password);
driver.switchTo().alert().accept();
}
How can I make the 1st solution work?
Related
Does PageFactory.initElements(driver,this) try to initialize all element written in the page?
I have login page where only username and login button is there. once i enter username and hit login then password box comes in.
I have written username,password and Login button findby method in LoginPage class. Now before entering username and clicking on login button, i am trying to initilize the LoginPage. As the password field is not there will it throw error ?
Thanks,
I got the answer after doing lots of googling and debugging my page factory code initialization.
When we try to initialize the page using pagefactory init element it creates the proxy of each element and when we call webelement to do some actions on it like element.click() then it try to find the element in the page where you are right now.
One good post i found is at:
https://rationaleemotions.wordpress.com/2016/09/05/understanding-pagefactory/
I am creating a framework in selenium from scratch where i am scripting below scenarios:
1.Login in to https://www.yahoomail.com
2.entering username
3.entering password
4.click on Sign-In
5.click on Compose button
6.Enter Email ID, Subject and Message body.
Below is the code script i have written for above scenario:
WebDriver oYahoo = new FirefoxDriver();
oYahoo.get("http://www.yahoomail.com/");
oYahoo.manage().window().maximize();
oYahoo.findElement(By.xpath(".//*[#id='login-username']")).sendKeys("abcdefasdf#yahoo.com");
oYahoo.findElement(By.xpath(".//*[#id='login-passwd']")).sendKeys("sfgas234#123");
oYahoo.findElement(By.xpath(".//*[#id='login-signin']")).click();
oYahoo.findElement(By.xpath(".//*[#id='Compose']/button")).click();
oYahoo.findElement(By.xpath(".//*[#id='yui_3_16_0_1_1448364357109_2222']")).sendKeys("abcdefgh#gmail.com");
oYahoo.findElement(By.xpath(".//*[#id='subject-field']")).sendKeys("Hi This is my first automated mail");
oYahoo.findElement(By.xpath(".//*[#id='yui_3_16_0_1_1448364357109_1966']")).sendKeys("Hi This is my first automated mail");
oYahoo.findElement(By.xpath(".//*[#id='yui_3_16_0_1_1448364357109_2465']")).click();
oYahoo.quit();
Scripts fine till it clicks on "Compose" button, Once i get Mail editor, Script does not enters email-ID,Subject, and Message body.
What other action i should perform to achieve the same so that script will enter these parameters and can send a mail to particular user.
Do we need to create some class which will maps the locators to "compose-Email" screen?
If yes, how we can map/assign x-path to particular web element of Compose-Email page.
Thanks in Advance.
Well you should try by using the xpath and enter the required text. Something like this (it works for me)-
oYahoo.findElement(By.xpath(".//*[#id='to-field']")).sendKeys("xxxx#xxx.com");
oYahoo.findElement(By.xpath(".//*[#id='subject-field']")).sendKeys("My first automated email");
oYahoo.findElement(By.id("rtetext")).sendKeys("Hello....Hi....This is my first automated email");
The problem I'd like to solve is the following:
I need to manage an external web page through PHP, for example, login and then change the profile info on the external web after sending an ajax request on my own web.
For this, I'm calling PhantomJS from PHP to do those tasks, but before login to the external web I need to fill the captcha input. So, I'd like to send back the Captcha image to my web, write the correct code and send it back to the WebPage module of PhantomJS to login using that code.
In other words, I need a 'syncronous' program like this:
1) PHP -> Send a request to login and obtain the captcha image.
2) PhantomJS -> Open a WebPage instance and render the captcha code to an image.
3) PHP -> Get the captcha image, show it to an user and send a text input to PhantomJS.
4) PhantomJS -> Get the text code from PHP, fill the captcha input using 'page.evaluate' and login. Send to PHP some data ('Login successfull', 'Login failed', etc)
5) PHP -> Get the callback and send another task or data.
callback = 'Login successfull' --> Change profile picture or update user info.
callback = 'Login failed' --> Try to login again (like point 1)
Etc...
There are many things I don't know how to handle. For example:
1) How could I keep the WebPage module open and waiting for the text code of the captcha? If I close it, a new captcha code will appear next time, and I need a way to wait the code and get it. Do I need to start a server for this?
2)Get the captcha image from PHP isn't a problem (because of 'page.render'), but how I could send a text back to the WebPage instance of PhantomJS? I think is better to send data bidirectionally between both systems. Again, do I need a server?
I think I need a socket server in PhantomJS (how can this be done?). This server should have the WebPage instance that I need to keep open, but I'm not completely sure about this.
Thanks.
I recently published a project that gives PHP access to a browser. Get it here: https://github.com/merlinthemagic/MTS, Under the hood is an instance of PhantomJS.
The main issue is keeping a resource alive after initial execution. Here is how i propose you do it.
After downloading and setup you would simply use the following code:
Start of "Setup" session:
if (isset($_POST['sessionUID']) === false) {
//set the execution timeout long enough to cover the entire process (setup and working time), it dictates when phantomJS shuts down automatically.
ini_set('max_execution_time', 300);
//open the login page:
$myUrl = "http://www.example.com";
$browserObj = \MTS\Factories::getDevices()->getLocalHost()->getBrowser('phantomjs');
//allow the page to live after php shuts down.
$browserObj->setKeepalive(true);
$windowObj = $browserObj->getNewWindow($myUrl);
//find the username input box, here it has id=username
$windowObj->mouseEventOnElement("[id=username]", 'leftclick');
//type your username
$windowObj->sendKeyPresses("yourUsername");
//find the password input box, here it has id=passwd
$windowObj->mouseEventOnElement("[id=passwd]", 'leftclick');
//type your password
$windowObj->sendKeyPresses("yourPassword");
//click on the login button, here it has id=login
$windowObj->mouseEventOnElement("[id=login]", 'leftclick');
//i assume this is when you encounter the CAPTCHA image
//find the CAPTCHA image element, here it has id=captchaImage
$element = $windowObj->getElement("[id=captchaImage]");
$loc = $element['location'];
//tell the screenshot to only get the CAPTCHA image
$windowObj->setRasterSize($loc['top'], $loc['left'], ($loc['right'] - $loc['left']), ($loc['bottom'] - $loc['top']));
$imageData = $windowObj->screenshot("png");
$sessionUID = uniqid();
$saveWindowObj = serialize($windowObj);
//save the window object so we can pick it up again
file_put_contents("/tmp/" . $sessionUID, $saveWindowObj);
}
//now render the CAPTCHA image to the user as part of a form they can resubmit and make sure to keep the $sessionUId as a hidden variable in the form on the page
End of the "Setup" session, php shuts down here.
Start of "Working" session:
We assume the user submits the form and it is a post containing the $sessionUID and the text string for CAPTCHA.
if (isset($_POST['sessionUID']) === true && isset($_POST['captchaTxt']) === true) {
$savedWindow = file_get_contents("/tmp/" . $sessionUID);
//delete the saved object
unlink("/tmp/" . $sessionUID);
//bring back the object to life
$windowObj = unserialize($savedWindow);
//make sure the browser is now shutdown on exit
$windowObj->getBrowser()->setKeepalive(false);
//find the CAPTCHA input box, here it has id=captchaInput
$windowObj->mouseEventOnElement("[id=captchaInput]", 'leftclick');
//type the CAPTCHA string
$windowObj->sendKeyPresses($_POST['captchaTxt']);
//click on the button to accept CAPTCHA, here it has id=captchaOK
$windowObj->mouseEventOnElement("[id=captchaOK]", 'leftclick');
//now use the clickElement() etc functions on $windowObj to do what you need to do.
}
End of the "Working" session, php shuts down here.
I've started learning selenium web driver. I've come across an issue. When I navigate to my URI, I come across an windows authentication window before I can access my web page. Im using C# for the scripting. Ive got the code that I should be using:
// Get the page elements
var userNameField = driver.FindElementById("usr");
var userPasswordField = driver.FindElementById("pwd");
var loginButton = driver.FindElementByXPath("//input[#value='Login']");
// Type user name and password
userNameField.SendKeys("admin");
userPasswordField.SendKeys("12345");
But this is only good if you have a normal login page. I can't get to the elements or get the Fire Path id as the window authentication pop will not let me. Can someone please help me with this. How do I automate this process
Thanks
We have a way to handle this by passing username and password inside URL like the following:
driver.Navigate().GoToUrl(https://<username>:<password>#<URL>");
e.g.
driver.Navigate().GoToUrl(https://auth_user1:userpassword1#www.google.com");
Hope this helps!
Hy... i want to login to some 3rd party sites using HtmlUnit. But HtmlUnit should be able to tell me whether the login attempt to the input site is successful or not. Is there any way around to perform this task using HtmlUnit. Please help ..!!!
Thanks
Usman Raza
I'm currently using HTMLunit to log in to a site that has a varification page and redirect. some of my code for this is:
//---------------------------------Login Page---------------------------------
HtmlPage PageLogin = webClient.getPage(url);
HtmlElement submitButton = (HtmlElement) PageLogin.getByXPath(Xpath To Button).get(0);
HtmlTextInput name = (HtmlTextInput) PageLogin.getElementById("UserIdInput");
HtmlPasswordInput pass = (HtmlPasswordInput)PageLogin.getElementById("ADloginPasswordInput");
name.setText(username);
pass.setText(password);
System.out.println("Logging in to site");
//------------------------------------------------------------------------
//---------------------------------Pass varified Page----------------------
HtmlPage pagePassVarified = submitButton.click();
System.out.println("Successfully Logged in to site");
HtmlElement btnContinue = (HtmlElement) pagePassVarified.getElementById("BtnClickToContinue");
//---------------------------------------------------------
//---------------------Home Page----------------------------------
HtmlPage pageHome = btnContinue.click();
System.out.println("Home Page accessed");
//----------------------------------------------------------------
This code goes to a login page, adds username and passwords to text boxes, and clicks the submit button. We are next redirected to a "wait 5 seconds, or click here to continue to home page" type of page, where the continue button is clicked. Lastly we arrive at our home page that we wanted to log into. I selected the page elements by both ID and Xpath when no ID was available.
You can have HtmlUnit check the URL, or search for a specific element on the page, more precisely one you know to be present only in one case (sucessful login / rejected).
Like RabidFX suggested, I would suggest you to check URL but in some cases (I've seen such situations in my work experience) URL may still the same. Then, my suggestion would be checking for a specific element and it should be the login form because generally unsuccessfull login attemps redirect you to the same page that has the same login form. That would not be hard - coded solution because I hope you have found some way to get that login form with a generic way :)