WebDriverEventListener and loggin sendKeys data - selenium

I have been using WebDriverEventListener to log various message and one of them is the data used by sendKeys method. API -org.openqa.selenium.support.events.WebDriverEventListener#beforeChangeValueOf can be used to log messages before keying in data in text field. But I get access to only element locator using WebElement argument. Is there a way to also access data which is keyed in to element?

Before change method you are providing element locator, so you get the value as you do for an input field. Implement the beforeChangeValueOf method as follows-
public void beforeChangeValueOf(WebElement element, WebDriver arg1) {
System.out.println("Before change: "+element.getAttribute("value"));
}

Use the method:
public void afterChangeValueOf(WebElement element,
WebDriver driver,
java.lang.CharSequence[] keysToSend);
keysToSend parameter will give you the keyed data.

Related

Assert name field of registration process with sendKeys java selenium

I have an automation running on a website with registration process.
I need to assert all fields on registration: name, email, pass, confirmPass.
If for example I run my test as follows it always fails since the Actual always remains empty. what am I missing here with the sendKeys ?
InsertXpathAndClick
InsertIDAndKeysToSend
etc are shortcuts to find elements and click or send keys (they operate as expected on other parts of my program)
#Test
public void TestAssertName() {
SingeltonDriver.driver.navigate().to("https://buyme.co.il");
SingeltonDriver.driver.manage().window().maximize();
SingeltonDriver.driver.manage().timeouts().implicitlyWait(7, TimeUnit.SECONDS);
InsertXpathAndClick("//*[#id=\"ember676\"]/div/ul[1]/li[3]/a/span[2]");
InsertXpathAndClick("//*[#id=\"ember650\"]/div/div[1]/div/div/div[3]/p/span");
SingeltonDriver.driver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);
//This is the interesting part of checking the name val that i sent VS the one that i get by getText.
InsertIDAndKeysToSend("ember1179", "Kate");
WebElement ActualName = SingeltonDriver.driver.findElement(By.id("ember1179"));
String ActualNameUpdated = ActualName.getText();
Assert.assertEquals("Kate", ActualNameUpdated);
}

selenium clear() command doesn't clear the element

I have been writing selenium scripts for a while in Java. I encountered a very weird issue today. Here is the issue:
I cleared a text field using webelement.clear() method, later while executing next command (click event), the text area I had previously cleared, is now populated with previously filled value.
Here is the code snippet:
mobileNumField.get(0).clear();
Thread.sleep(4500);
emailAddress.get(0).click();
emailAddress.get(0).clear();
Thread.sleep(4500);
emailAddress.get(0).sendKeys(Keys.TAB);
I don't know the exact reason for your element keeping its value, but you can try an alternative text clearance by sending 'Ctrl+A+Delete' key combination using sendKeys method of the element's object:
emailAddress.sendKeys(Keys.chord(Keys.CONTROL,"a", Keys.DELETE));
It's possible that the fields you're trying to fill has autocomplete attribute set to on. [Reference]
If clear() works when the line executes then it's safe to say that this is not a webdriver specific issue.
It would help if you can show the html snippet of the page section you're working on.
Possible areas of debugging:
forcefully remove autocomplete attribute on page load using java script executor
turn off autocomplete setting on the driver level. I believe the solution would vary depending on the driver being used.
Good luck!
PS: Those Thread.sleep(s) are not advisable.
I solved it by adding a function to my BasePage to clear fields by a given WebElement.
public void clearWebField(WebElement element){
while(!element.getAttribute("value").equals("")){
element.sendKeys(Keys.BACK_SPACE);
}
}
You can also implement this method in the page that experiencing the problem.
I am using Mac and the following code helps also
public static void macCleanHack(WebElement element) {
String inputText = element.getAttribute("value");
if( inputText != null ) {
for(int i=0; i<inputText.length();i++) {
element.sendKeys(Keys.BACK_SPACE);
}
}
}
I had a similar issue with a text field that used an auto-complete plugin. I had to explicitly clear the attribute value as well as do a SendKeys. I created an extension method to encapsulate the behaviour, hopefully the snippet below will help:
public static void SendKeysAutocomplete(this IWebElement element, string fieldValue)
{
element.SendKeys(fieldValue);
element.SetAttribute("value", fieldValue);
}
public static void SetAttribute(this IWebElement element, string attributeName, string attributeValue)
{
var driver = WebDriverHelper.GetDriverFromScenarioContext();
var executor = (IJavaScriptExecutor)driver;
executor.ExecuteScript("arguments[0].setAttribute(arguments[1], arguments[2]);", element, attributeName, attributeValue);
}
Faced a similar problem. The input field is cleared but the error message is not updated. It seems that some input fields work correctly only if you enter and delete a character:
element.sendKeys(text);
element.sendKeys(Keys.SPACE, Keys.BACK_SPACE);
Hope this helps to clear the field and then sendKeys() the needed value
while (!inputField.getAttribute("value").equals("")) {
inputField.sendKeys(Keys.BACK_SPACE);
}
inputField.sendKeys("your_value");
In some webforms clearing the field followed by .sendKeys() won't work because it keeps repopulating it with some autofill value (in my case it was due to an onfocus attribute function of an input element). Action chains didn't help, the only thing that worked for me was replacing the value attribute directly with javascript:
In Java:
driver.executeScript("document.getElementById('elementID').value='new value'");
In Python (nearly identical):
driver.execute_script("document.getElementById('elementID').value='new value'")
For more on the Java version of this solution see this question.

Selenium WebDriver based framework using POM with java

I am trying to write code to validate a webpage (Test Form with 3 required fields firstname, lastname, phone and 2 buttons submit and clear form) using POM with Selenium WebDriver with Java.
This is the code which I have written so far. I want to confirm whether I am going in the right way.
public class TestForm {
WebDriver driver;
By firstName=By.id("fname");
By lastName=By.id("lname");
By phoneno=By.id("phone");
By submit=By.id("submit");
By clearForm=By.xpath("//tagname[#type='button']");
public TestForm(WebDriver driver)
{
this.driver=driver;
}
public void typeFirstName(String fname)
{
driver.findElement(firstName).sendKeys(fname);
}
public void typeLastName(String lname)
{
driver.findElement(lastName).sendKeys(lname);
}
public void typePhone(String phone)
{
driver.findElement(phoneno).sendKeys(phone);
}
public void clickSubmit()
{
driver.findElement(submit).click();
}
public void clickClearForm()
{
driver.findElement(clearForm).click();
}
}
public class VerifyTestForm {
#Test
public void verifyValidTestForm()
{
WebDriver driver=new FirefoxDriver();
driver.manage().window().maximize();
driver.get("url of the application");
TestForm form=new TestForm(driver);
form.typeFirstName("John");
form.typeLastName("Adams");
form.typePhone("1234567890");
form.clickSubmit();
form.clickClearForm();
driver.quit();
}
}
Most code look good, except following items:
1) By clearForm=By.xpath("//tagname[#type='button']");
tagname should be a correct tag, like button or 'input'
2) After click Submit, the page still stay the form page, If so call clickClearForm should work.
form.clickSubmit();
form.clickClearForm();
3) There is no any check point/validation in your code, all are operateion on page.
// Assume an new page will open after click Submit button
// You need to check the new page opened by check page title if it'll change
// or check an element belongs to the new page is displayed
Assert(driver.getTitle()).toEqual('xxx')
Assert(driver.findElement(xxx).isDisplay()).toBe(true)
// above code may not exact correct, dependent on you choose Junit, TestNG
// or third-party Assert library.
// After click `Clear/Reset` button, you should check all fields reset to default value
Assert(form.readFirstName()).toEqual("")
4) For test class name VerifyTestForm, it's better start or end with Test, like Testxxx or xxxTest
As your code is correct but it is not the way to implementing Page object Model.
You have to use concept of DataProvider to implement framework.
Make a excel sheet and extract the data by using DataProvider.
Make a new class file from where you can read your excel data.
Make a function which return 2d data of the file.
So By using this, The way to implement the framework.
Page object Model generally says that we should have to make the separate page of each module which we are using and return the reference of the last page.

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

How to use "isTrue" method of "Text" class?

I am unable to use "isTrue" method of text class
Here is the "Text" class detail
http://selenium.googlecode.com/git/docs/api/java/index.html
// Code i have written
public void researchSelenium(){
driver.get(baseUrl);
ConditionRunner.Context cont = new Research();
Text obj = new Text("Why implement a customer referral program?");
System.out.println(obj.isTrue(cont));
driver.close();
driver.quit();
I dont know what to do here
ConditionRunner.Context cont = new Research(); //After "new" what should i write?
object of ConditionRunner.Context will pass to "isTrue" method
I'm going to make a few presumptions here:
driver is a selenium web driver instance
You are trying to find if a text field is present in your web page
You know what the text is, but not its xpath (or at least do not care "where" it is).
In this case, you just have a minor syntaxical error
public void researchSelenium()
{
driver.get(baseUrl);
//Not sure what this is doing.
ConditionRunner.Context cont = new Research();
//Small chgange here
string obj = "Why implement a customer referral program?";
System.out.println(driver.isTextPresent(obj));
driver.close();
driver.quit();
}
NB. the above is "free coded" and I've not tested/complied it. Feel free to edit if there's a minor problem.
APPEND:
Personally I'd use NUnit to handle tests, so in that case I'd use:
Assert.isTrue(driver.isTextPresent(obj));
To test if that text was actually present, but how you're running your tests is not something that's stated in your question.