Get Attributes of a Hidden Element - java

I have a table I am trying to test. Inside one of the columns is yes/no radio buttons which when the page is rendered is hidden underneath an image so that there is a check-mark or an X when yes or no is selected.
The attribute for the radio button when yes is selected checked="true".
How do I with Selenium2 get that attribute so that I can compare it or make assertions against it?
I have tried the following, which simply results in a null pointer error.
private void verifyPOEligibleYesNull(String driverName)
{
int min = 1;
int max = 6;
JavascriptExecutor js = (JavascriptExecutor)driver;
StringBuilder stringBuilder = new StringBuilder();
//Navigate to System Facing
driver = browser.getDriver(driverName);
driver.manage().window().maximize();
driver.navigate().to("http://theURL");
//Enter userName
WebElement userName = driver.findElement(By.id("username"));
userName.clear();
userName.sendKeys(user);
//Enter Password
WebElement password = driver.findElement(By.id("pword"));
password.clear();
password.sendKeys(pwd);
//Click Login
WebElement loginBtn = driver.findElement(By.xpath("/html/body/div/div/form/div[3]/div/input"));
loginBtn.click();
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
WebElement ivToPoBtn = driver.findElement(By.xpath("/html/body/div/div/div/ul/li/a/img"));
ivToPoBtn.click();
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
//Grab a random row and determine whether the PO Eligible is "Yes"
String rowNum = Integer.toString(rand.nextInt(max - min + 1) + min);
WebElement randomRow = driver.findElement(By.xpath("/html/body/div/div/div/div/form/div/div[2]/div/div[2]/div/div/div/div/div/div/div/table/tbody/tr["+rowNum+"]/td/div/div/input"));
String poEligibleChecked = randomRow.getAttribute("checked").toString();
stringBuilder.append("var x = $(\""+poEligibleChecked+"\");");
stringBuilder.append("return x.toString();");
String res = (String) js.executeScript(stringBuilder.toString());
System.out.println(res);
}
I have even tried the following which was suggested from WebDriver FAQ:
WebElement randomRow = driver.findElement(By.xpath("/html/body/div/div/div/div/form/div/div[2]/div/div[2]/div/div/div/div/div/div/div/table/tbody/tr["+rowNum+"]/td/div/div/input"));
String poEligibleChecked = randomRow.getAttribute("checked");
String element = js.executeScript("return arguments[0].getText();", poEligibleChecked).toString();
System.out.println(element);
With similar null pointer exception error.

Your code doesn't really make sense. In order to get the checked attribute of an invisible element, simply use element.getAttribute():
final String scriptGetChecked = "return arguments[0].getAttribute('checked')";
WebElement randomRow = driver.findElement(By.whatever("something"));
String checkedState = (String) js.executeScript(scriptGetChecked, randomRow);

Related

Unable to select/click second and last element on mouse hover in selenium

Below is the screenshot of the mouse hover event.
Style type
It is triggered only on mouse hover. Currently, I'm able to read the Style Type Text. I can select the first element without any issues, however, I'm unable to click the second and last element (Categorized and Graduated ).
UI Code for reference.
UI code
Below is the Selenium code for reference.
static void styletype() throws InterruptedException {
Thread.sleep(1000);
String sname = null;
// select style type
Actions action = new Actions(driver);
WebElement menu = driver.findElement(By.xpath("//*[#src = 'assets/images/down_arrow.svg']"));
action.moveToElement(menu).perform();
Thread.sleep(1500);
List<WebElement> rowsList = driver.findElements(By.xpath("//*[contains(#class,'dropdown-item')]"));
for (WebElement element : rowsList) {
try {
sname = element.getText();
// System.out.println("File Type is : " + sname);
int result = JOptionPane.showConfirmDialog(frame, "Layer Stype Type : '" + sname + "'",
"Do you want to continue", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == 0) {
element.click();
break;
}
action.moveToElement(menu).perform();
Thread.sleep(1000);
} catch (Exception e) {
}
}
}

Java Selenium + 2Captcha + Submit Form

Hello i am trying to automate some process here . i am using 2captch to solve captcha , please check out image .
I have got site_key and api_key , now i am sending api_key + site_key and it is returning me response_token, i have added returned response token into g-recaptcha-response but it is not submitting form.
what i want is that : i can solve captcha and submit form .
Here is my current java code :
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
ChromeDriver driver;
driver = new ChromeDriver();
driver.manage().deleteAllCookies();
driver.manage().window().maximize();
driver.get("https://id.sonyentertainmentnetwork.com/signin/?client_id=fe1fdbfa-f1a1-47ac-b793-e648fba25e86&redirect_uri=https://secure.eu.playstation.com/psnauth/PSNOAUTHResponse/pdc/&service_entity=urn:service-entity:psn&response_type=code&scope=psn:s2s&ui=pr&service_logo=ps&request_locale=en_GB&error=login_required&error_code=4165&error_description=User+is+not+authenticated&no_captcha=false#/signin?entry=%2Fsignin");
Thread.sleep(5000);
driver.findElement(By.xpath("//input[#title='Sign-In ID (Email Address)']")).sendKeys("email");
Thread.sleep(2000);
driver.findElement(By.xpath("//input[#title='Password']")).sendKeys("password");
Thread.sleep(2000);
driver.findElement(By.xpath("//button[#class='primary-button row-button text-button touch-feedback']")).click();
Thread.sleep(3000);
By captcha = By.xpath("//iframe[#title='recaptcha challenge']");
String src = driver.findElement(captcha).getAttribute("src");
String key = getKey(src);
System.out.println(key);
String apiKey = "API_KEY";
String googleKey = key;
String pageUrl = "https://id.sonyentertainmentnetwork.com/signin/?client_id=fe1fdbfa-f1a1-47ac-b793-e648fba25e86&redirect_uri=https://secure.eu.playstation.com/psnauth/PSNOAUTHResponse/pdc/&service_entity=urn:service-entity:psn&response_type=code&scope=psn:s2s&ui=pr&service_logo=ps&request_locale=en_GB&error=login_required&error_code=4165&error_description=User+is+not+authenticated&no_captcha=false#/signin?entry=%2Fsignin";
String proxyIp = "183.38.231.131";
String proxyPort = "8888";
String proxyUser = "username";
String proxyPw = "password";
TwoCaptchaService service = new TwoCaptchaService(apiKey, googleKey, pageUrl, proxyIp, proxyPort, proxyUser, proxyPw, ProxyType.HTTP);
try {
String responseToken = service.solveCaptcha();
System.out.println("The response token is: " + responseToken);
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("document.getElementById(\"g-recaptcha-response\").innerHTML = \'"+responseToken+"\';");
} catch (InterruptedException e) {
System.out.println("ERROR case 1");
e.printStackTrace();
} catch (IOException e) {
System.out.println("ERROR case 2");
e.printStackTrace();
}
UPDATED CODE :
js.executeScript("document.getElementById(\"g-recaptcha-response\").innerHTML = \'" + responseToken + "\';");
Thread.sleep(500);
WebElement frameElement = driver.findElement(captcha);
driver.switchTo().frame(frameElement);
js.executeScript("document.getElementById('recaptcha-verify-button').click();");
it is clicking on button but , it shows Please select all matching images.
. please check out screenshot
All you need to do is submit it like this:
js.executeScript("document.getElementById('g-recaptcha-response').innerHTML='" + responseToken + "';");
Thread.sleep(500);
js.executeScript("document.getElementById('captcha-form').submit();");
also don't forget to check this ID : "captcha-form", it can be different
To reach to element "recaptcha-verify-button":
After you got the response from the API;
By frame = By.xpath("//iframe[#title='recaptcha challenge']");
WebElement frameElement = driver.findElement(frame);
driver.switchTo.frame(frameElement);
then you can execute your script. Finally, for your script if your captcha form is a button
you
cannot call submit();
you
can call click();
Final Answer:
Also check this: js.executeScript("widgetVerified('TOKEN');");
To find the function called widgetVerified() please run this code in the console.
___grecaptcha_cfg.clients[0]
this will return a json, inside of that json try to find the callback function in #Awais case it was wigdetVerified(e)
Warn : Don't use any adblocker

Stale Object Reference while Navigation using Selenium

I have been trying a simple program that navigates and fetches data from the new page, comes back in history and open other page and fetch data and so on until all the links have been visited and data is fetched.
After getting results on the below site, i am trying to loop through all the links i get in the first column and open those links one by one and extract text from each of these page. But the below program only visits first link and gives StaleElementReferenceException, I have tried using Actions but it didn't work and I am not aware about JavascriptExecutor. I also tried solutions posted on other SO questions, one of which was mine over here. I would like to have the mistake corrected in the below code and a working code.
public class Selenium {
private final static String CHROME_DRIVER = "C:\\Selenium\\chromedriver\\chromedriver.exe";
private static WebDriver driver = null;
private static WebDriverWait wait = null;
private void setConnection() {
try {
System.setProperty("webdriver.chrome.driver", CHROME_DRIVER);
driver = ChromeDriver.class.newInstance();
wait = new WebDriverWait(driver, 5);
driver.get("https://sanctionssearch.ofac.treas.gov");
this.search();
} catch (Exception e) {
e.printStackTrace();
}
}
private void search() {
try {
driver.findElement(By.id("ctl00_MainContent_txtLastName")).sendKeys("Dawood");
driver.findElement(By.id("ctl00_MainContent_btnSearch")).click();
this.extractText();
} catch (Exception e) {
e.printStackTrace();
}
}
private void extractText() {
try {
List<WebElement> rows = driver.findElements(By.xpath("//*[#id='gvSearchResults']/tbody/tr"));
List<WebElement> links = null;
for (int i = 1; i <= rows.size(); i++) {
links = driver.findElements(By.xpath("//*[#id='gvSearchResults']/tbody/tr/td[1]/a"));
for (int j = 0; j < links.size(); j++) {
System.out.println(links.get(j).getText() + ", ");
links.get(j).click();
System.out.println("Afte click");
driver.findElement(By.id("ctl00_MainContent_btnBack")).click();
this.search();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] ar) {
Selenium object = new Selenium();
object.setConnection();
}
}
Generally we will be getting the Stale Exception if the element attributes or something is changed after initiating the webelement. For example, in some cases if user tries to click on the same element on the same page but after page refresh, gets staleelement exception.
To overcome this, we can create the fresh webelement in case if the page is changed or refreshed. Below code can give you some idea.
Example:
webElement element = driver.findElement(by.xpath("//*[#id='StackOverflow']"));
element.click();
//page is refreshed
element.click();//This will obviously throw stale exception
To overcome this, we can store the xpath in some string and use it create a fresh webelement as we go.
String xpath = "//*[#id='StackOverflow']";
driver.findElement(by.xpath(xpath)).click();
//page has been refreshed. Now create a new element and work on it
driver.fineElement(by.xpath(xpath)).click(); //This works
In this case, we are collecting a group of webelements and iterating to get the text. But it seems there is some changes in the webelement after collecting the webelements and gettext throws staleness. We can use a loop and create the element on the go and get text.
for(int i = 0; i<5; i++)
{
String value = driver.findElement(by.xpath("//.....["+i+"]")).getText);
System.out.println(value);
}
Hope this helps you. Thanks.
The reason you get StaleElementReference Exception, is normally because you stored element(s) into some variable, however after that you did some action and page has changed (due to some ajax response) and so your stored element has become stale.
The best solution is not to store element in any variable in such case.
This should work.
links = driver.findElements(By.xpath("//*[#id='gvSearchResults']/tbody/tr/td[1]/a"));
for (int j = 0; j < links.size(); j++) {
System.out.println(links.get(j).getText() + ", ");
driver.findElements(By.xpath("//*[#id='gvSearchResults']/tbody/tr/td[1]/a")).get(j).click();
System.out.println("Afte click");
driver.findElement(By.id("ctl00_MainContent_btnBack")).click();
this.search();
}
Please check this code
private void extractText() {
try {
List<WebElement> rows = driver.findElements(By.xpath("//*[#id='gvSearchResults']/tbody/tr"));
List<WebElement> links = null;
System.out.println(rows.size());
for (int i = 0; i < rows.size(); i++) {
links = driver.findElements(By.xpath("//*[#id='gvSearchResults']/tbody/tr/td[1]/a"));
WebElement ele= links.get(0);
System.out.println(ele.getText() + ", ");
ele.click();
System.out.println("After click");
driver.findElement(By.id("ctl00_MainContent_btnBack")).click();
}
} catch (Exception e) {
e.printStackTrace();
}
}

Selenium Webdriver - The entered text is vanished when jumping to the next field

I am trying to enter the text and ensure it gets saved. In my project, there is no save button, as soon as it entered it gets saved. Only few fields that cracks me when entering the text.
Note: I'm using the latest version of Chrome and passing the numeric values as text.
I referred to below pages and updated my code accordingly, then also this issue persists:
Selenium Webdriver: Entering text into text field
Selenium send_keys doesn't work if input type="number"
Below is the code that I used,
public void EnterValuesByIndex(String locator, String locatorValue, String text, int indexvalue) throws InterruptedException
{
WebElement element = null;
if (locator.equalsIgnoreCase("cssSelector")) {
element = (WebElement)driver.findElements(By.cssSelector(locatorValue)).get(indexvalue - 1);
} else if (locator.equalsIgnoreCase("xpath")) {
element = (WebElement)driver.findElements(By.xpath(locatorValue)).get(indexvalue - 1);
} else if (locator.equalsIgnoreCase("id")) {
element = (WebElement)driver.findElements(By.id(locatorValue)).get(indexvalue - 1);
}
//element.clear();
element.sendKeys(text);
Thread.sleep(2000);
element.sendKeys(Keys.ENTER);
System.out.println("Enter key is pressed");
}
Below code also used to enter character by character, same issue persists,
public void EnterTextbyChar(String locator, String locatorValue, String text, int indexvalue) throws InterruptedException
{
String value = text;
WebElement element = null;
if (locator.equalsIgnoreCase("cssSelector")) {
element = (WebElement)driver.findElements(By.cssSelector(locatorValue)).get(indexvalue - 1);
} else if (locator.equalsIgnoreCase("xpath")) {
element = (WebElement)driver.findElements(By.xpath(locatorValue)).get(indexvalue - 1);
} else if (locator.equalsIgnoreCase("id")){
element = (WebElement)driver.findElements(By.id(locatorValue)).get(indexvalue - 1); }
element.clear();
for (int i = 0; i < value.length(); i++)
{
char c = value.charAt(i);
String s = new StringBuilder().append(c).toString();
element.sendKeys(s);
element.sendKeys(Keys.RETURN);
element.click();
Thread.sleep(2000);
System.out.println("Return key is pressed in EnterTextByChar method");
System.out.println(c);
}
}
Finally a solution found. After entering the text, sending the upwards key that worked perfectly.
element.sendKeys(text);
element.sendKeys(Keys.UP);
If other options don't work, try
element.sendKeys(text);
element.sendKeys(Keys.RETURN);

Selenium Java Chrome: Stale exception

Here is a code fragment:
System.setProperty(Constants.WEBDRIVER_CHROME_DRIVER_PROP, Constants.WEBDRIVER_CHROME_DRIVER_PATH);
m_chromeWebdriver = new ChromeDriver();
m_chromeWebdriver.get("mysite.org");
WebElement arrowElement = m_chromeWebdriver.findElement(By.cssSelector(_ARROW_NEXT_DAY));
arrowElement.click();
WebElement elmMainTable = m_chromeWebdriver.findElement(By.className("table-main"));
List<WebElement> allRows = elmMainTable.findElements(By.tagName("tr"));
for (WebElement row : allRows) {
List<WebElement> cells = row.findElements(By.tagName("td"));
for (WebElement cell : cells) {
System.out.println(cell.getText());
}
}
m_chromeWebdriver.quit();
At the last line I get an
"stale element reference: element is not attached to the page
document"
exception.
Why and how can I solve that?
I use Chromdriver 2.2.9.
Well, as this is probably not the perfect solution - at least it worked for me...
I put all the relevant code into a method like this:
private static void handleTable() {
for (int i = 1; i < 5; i++) {
try {
WebElement elmMainTable = m_chromeWebdriver.findElement(By.className("table-main"));
List<WebElement> allRows = elmMainTable.findElements(By.cssSelector(".table-main tr"));
for (WebElement row : allRows) {
List<WebElement> cells = row.findElements(By.tagName("td"));
for (WebElement cell : cells) {
System.out.print(cell.getText() + "\t");
}
System.out.println();
}
} catch (StaleElementReferenceException e) {
//e.printStackTrace();
handleTable();
}
return;
}
}
And it worked! You can change the value 5 to which ever you'd like of course.
I learned the main reason for Selenium stale exception is element changed in DOM. In case, the stale exception are caused by those web elements you are not handling, you can try below try-catch and continue method in JAVA.
//get webelement list of button on the OU tab
List<WebElement> ouList =
Logon.wDriver.findElements(By.tagName(PagePropertise.tagButton));
// it should be 6
System.out.println("List Size is: "+ouList.size());
for (int i=0; i<ouList.size(); i++ ) {
//get each button element to verify with input Org name
WebElement ouName= ouList.get(i);
String ouLabel = null;
try {
ouLabel = ouName.getText();
} catch (StaleElementReferenceException e) {
//handle in exception catch, just skip invalid element and continue for to handle rest of loop
System.out.println("WebElement "+i+" = text "+ ouLabel);
continue;
}
System.out.println("WebElement "+i+" = text "+ ouLabel);
//webelement processing
...
//for some reason some of webelements in the OUlist were changed for above processing code.
}

Categories