Error while checking the clickable web element - java

I am facing problem while checking the clickable web element.
So i have to check the alphabetic series and some of the alphabet are clickable and some are not clickable.
i used for loop for it starting with xpath of alphabet 'A'
and going in loop till alphabet 'Z'.
but as soon as xpath of alphabet A is click & pass it goes to alphabet 'B'
which is not clickable and due to this whole script is getting fail.
here is the code
for(int j=3; j<=26;j++) {
String T1 =".//*[#id='twctvEl']/div/div/div[1]/ul/li[";
String T2 = "]/a";
String T12 = T1+j+T2;
chrome.findElement(By.xpath(T12)).click();
String alpha =chrome.findElement(By.xpath(T12)).getText();
System.out.println("checking the alphabet"+alpha);
}
Please advice here
NOTE: In the series of alpha bet from A-Z only B,Q,S,X,Y,Z are not clickable rest all are clickable.

You can add waits before element to become clickable:
for(int j=3; j<=26;j++)
{
String T1 =".//*[#id='twctvEl']/div/div/div[1]/ul/li[";
String T2 = "]/a";
String T12 = T1+j+T2;
WebElement el = chrome.findElement(By.xpath(T12));
WebDriverWait wait = new WebDriverWait(driver, timeout);
WebElement el= wait.until(ExpectedConditions.elementToBeClickable(element));
el.click();
String alpha =el.getText();
System.out.println("checking the alphabet"+alpha);
}

You can check if the element is visible and enabled before clicking on it
WebElement letter = chrome.findElement(By.xpath(T12));
if (letter.isDisplayed() && letter.isEnabled()) {
letter.click();
}

Well, it seems that when you click the element "A", it take you to another page or context and for this reason, during next iteration chrome driver is not able to find your Element "B" using xPath.

Related

Selenium WebDriver: Extracting strings in a search result using a loop

I'm trying to click on all the search results with a loop and get the title strings from each of the results. So it would click on a result try to extract the string.
String title = null;
List <WebElement> links = driver.findElements(By.className("thumbnail"));
ArrayList<String> tabs = new ArrayList<String> (driver.getWindowHandles());
for(int i=0; i<1; i++){
links = driver.findElements(By.className("thumbnail")); // this step is must, because whenever you go to other page all store WebElements in a list will wash out
links.get(i).click();
//it opens the search result in a new tab and gains focus on that tab
WebDriverWait wait = new WebDriverWait(driver, 10);
By addItem = By.xpath("//*[#id=\"HEADING\"]");
// get the "Add Item" element
WebElement element1 = wait.until(ExpectedConditions.presenceOfElementLocated(addItem));
wait.until(ExpectedConditions.stalenessOf(element1));
if(!driver.findElements(By.xpath("//*[#id=\"HEADING\"]")).isEmpty()) {
title = driver.findElement(By.xpath("//*[#id=\"HEADING\"]")).getText();
}
else {
System.out.println("Title is missing");
}
System.out.println(title);
driver.switchTo().window(tabs.get(0)); //Switching to first tab
}
The code is extracting the title on the first page rather than the page it clicked on. I'm also trying to extract other strings such as address, email, etc but i'm just testing this out. How do I fix this? Any help would be appreciated, thank you!
There were a few things that I changed.
I moved all your locators (and some other declarations) to the top and outside of the loop so they aren't redeclared inside the loop and so that they can be referenced by the .findElement() calls.
Since you are only using the current window handle, changed the variable type to String and just got the current window handle (instead of the collection of handles) so that you can switch back to the main tab at the end of the loop.
Moved the staleness check right after the click since that's where you need it and changed it to wait for the thumbnail that was just clicked.
Changed the XPath locator to use ID since that's all you were referencing. It's faster, shorter, and easier to read.
The second wait now waits for the collection of elements and then uses that collection to test for empty and get the text of the first in the collection.
By addItemLocator = By.id("HEADING");
By thumbnailsLocator = By.className("thumbnail");
List<WebElement> links = driver.findElements(thumbnailsLocator);
String originalTab = driver.getWindowHandle();
Set<String> tabs = driver.getWindowHandles();
WebDriverWait wait = new WebDriverWait(driver, 10);
for(int i = 0; i < links.size(); i++)
{
links = driver.findElements(thumbnailsLocator); // this step is must, because whenever you go to other page all store WebElements in a list will wash out
links.get(i).click();
// it opens the search result in a new tab and gains focus on that tab
// switch to the new window
for(String handle : driver.getWindowHandles()){
if (!handle.equals(originalTab))
{
driver.switchTo().window(handle);
break;
}
}
// get the "Add Item" element
List<WebElement> addItems = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(addItemLocator));
if(!addItems.isEmpty())
{
System.out.println(addItems.get(0).getText());
}
else
{
System.out.println("Title is missing");
}
driver.close(); // close current tab
driver.switchTo().window(originalTab); // switch to original tab
}

Java Selenium looping through website sendKeys combine strings together

I have a for loop that constantly loops back a website to fill out and submit a search box with the next string from a list.
For example, if the list contains [abcd, efgh, ijkl....], the first loop would send abcd, the second loop would send efgh and etc.
Currently the loop sends the first string correctly, but on every loop afterwards, the string sent is added to the previous string. So instead of efgh on the second loop, it is abcdefgh.
How do I clear the keys so that I can just send the individual string? Here's what I have right now:
for(String value : List){
driver.get(Link);
Actions actions = new Actions(driver);
WebElement input_field = driver.findElement(By.id("txtBoxSearch"));
actions.moveToElement(input_field);
actions.click();
actions.sendKeys(value);
actions.build().perform();
WebElement submit_key = driver.findElement(By.xpath("//button[contains(#title, 'Search')]"));
actions.moveToElement(submit_key);
actions.click();
actions.build().perform();
}
You need to clear the content of textbox before write value to it
for(String value : List){
driver.get(Link);
Actions actions = new Actions(driver);
WebElement input_field = driver.findElement(By.id("txtBoxSearch"));
input_field.clear();
actions.moveToElement(input_field);
actions.click();
actions.sendKeys(value);
actions.build().perform();
WebElement submit_key = driver.findElement(By.xpath("//button[contains(#title, 'Search')]"));
actions.moveToElement(submit_key);
actions.click();
actions.build().perform();
}
Here is the Answer to your Question:
Once you call click() method on the on the desired element through action class instance, next use the action class instance to clickAndHold, send CONTROL A and then send the new text DebanjanB to the form control to overwrite the previous text as follows:
for(String value : List){
driver.get(Link);
Actions actions = new Actions(driver);
WebElement input_field = driver.findElement(By.id("txtBoxSearch"));
actions.moveToElement(input_field);
actions.click();
actions.clickAndHold(input_field).sendKeys(Keys.chord(Keys.CONTROL, "a"), "DebanjanB").build().perform();
WebElement submit_key = driver.findElement(By.xpath("//button[contains(#title, 'Search')]"));
actions.moveToElement(submit_key);
actions.click();
actions.build().perform();
}
Let me know if this Answers your Question.

How to use navigate back in for each loop?

I want to click on an element inside a list and go to different page. In this page I m taking a string. Then I go back and do the same for others. But after one iteration my code can't find the second element and shuts down the browser. Am I using the navigator wrong?
Here is my code:
public MainPage ControlSorting() {
List <WebElement> listItems=driver.findElement(RESULTCONT).findElements(MEDIA);
String[] strImdb = new String[listItems.size()];
int l = 0;
for (WebElement ele1 : listItems) {
ele1.click();
WebElement element = getElementBy(ABOUTIMDB);
String a= element.getAttribute("ng-genre-action");
String[] parts = a.split(",");
strImdb[l]=parts[1];
l++;
driver.navigate().back();
}
return this;
}
After going back you have to re identify the object. Please add the following code inside for loop at the first line of your code.
listItems=driver.findElement(RESULTCONT).findElements(MEDIA);
This should work. Please try and let me know.

Selenium Java wait unitl text appears

I have a text box where I enter the text during tests, for example "cars", but very often not whole text appear in the text box, for example only "car". So my question is how can I wait until whole text will appear and how can I check that?
This
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.textToBePresentInElement(element, "text"));`
Doesn't work for me. It is the same result as without it.
[EDIT]
Thread.sleep(4000);
Doesn't work for me too.
Also
(new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
return d.findElement(...).getAttribute("value").length() != 0;
}
});
Will not work for me, because there is no value, because it is not saved.
You are close, the only thing missing is a loop to catch Selenium TimeOut Exceptions whilst you are polling the element. Also, I would rather go with the isDisplayed() instead of isTextPresent() and focus my Xpath on locating the 'cars' text that you are after.
Here is the method for waiting, it will return true/or false based on if the element was present during the polling time (10sec for example); worth noting that if the element is found as present earlier than the 10sec limit the loop will break and will return true:
public boolean waitForElement(String elementXpath, int timeOut) {
try{
WebDriverWait wait = new WebDriverWait(driver, timeOut);
boolean elementPresent=wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(elementXpath)).isDisplayed());
System.out.printf("%nElement is present [T/F]..? ")+elementPresent;
}
catch(TimeoutException e1){e1.printStackTrace();elementPresent=false;}
return elementPresent;
}
Now, it really boils down how you 'grab' the element. You mentioned, you want the full cars text to appear. Hypothetically speaking let's say the element is located by id=brand and you want the text inside an a href link. So you want something like this for your xpath:
//div[#id='brand']//a[text()[contains(., 'cars')]]
Please note that the above is case-sensitive so it will fail if you are looking for Cars.
Best of luck!
Update after OP's comment:
Correcting the way we identify the web-element:
//div[#id='widget_dijit_form_TextBox_0']//div//input
Now all is needed is to use the waitForElement above until the element appears. When it does you can grab the text by using:
String textInsideInputTag = elementPresent.getText();
Now you can compare this to your intended value (i.e. 'cars'):
if(textInsideInputTag.equals("cars")){
System.out.println("Successfully found cars inside <input> tag");
}
else{
System.out.println("Couldn't locate cars in the element!");
}

How many times a text appears in webpage - Selenium Webdriver

Hi I would like to count how many times a text Ex: "VIM LIQUID MARATHI" appears on a page using selenium webdriver(java). Please help.
I have used the following to check if a text appears in the page using the following in the main class
assertEquals(true,isTextPresent("VIM LIQUID MARATHI"));
and a function to return a boolean
protected boolean isTextPresent(String text){
try{
boolean b = driver.getPageSource().contains(text);
System.out.println(b);
return b;
}
catch(Exception e){
return false;
}
}
... but do not know how to count the number of occurrences...
The problem with using getPageSource(), is there could be id's, classnames, or other parts of the code which match your String, but those don't actually appear on the page. I suggest just using getText() on the body element, which will only return the page's content, and not HTML. If I'm understanding your question correctly, I think that is more what you are looking for.
// get the text of the body element
WebElement body = driver.findElement(By.tagName("body"));
String bodyText = body.getText();
// count occurrences of the string
int count = 0;
// search for the String within the text
while (bodyText.contains("VIM LIQUID MARATHI")){
// when match is found, increment the count
count++;
// continue searching from where you left off
bodyText = bodyText.substring(bodyText.indexOf("VIM LIQUID MARATHI") + "VIM LIQUID MARATHI".length());
}
System.out.println(count);
The variable count contains the number of occurrences.
There are two different ways to do this:
int size = driver.findElements(By.xpath("//*[text()='text to match']")).size();
This will tell the driver to find all of the elements that have the text, and then output the size.
The second way is to search the HTML, like you said.
int size = driver.getPageSource().split("text to match").length-1;
This will get the page source, the split the string whenever it finds the match, then counts the number of splits it made.
You can try to execute javascript expression using webdriver:
((JavascriptExecutor)driver).executeScript("yourScript();");
If you are using jQuery on your page you can use jQuery's selectors:
((JavascriptExecutor)driver).executeScript("return jQuery([proper selector]).size()");
[proper selector] - this should be selector that will match text you are searching for.
Try
int size = driver.findElements(By.partialLinkText("VIM MARATHI")).size();

Categories

Resources