Selenium how to click on this kind of link - java

I'm having trouble with this particular link because is dynamic, it doesn't have an specefic name or id, but i know that all those links are inside a span with has a class. I try to get a list of WebElements to get all the spans with the class "more" to get the bunch of links inside but i get this error:
org.openqa.selenium.WebDriverException: Element is not clickable at point (96, 21). Other element would receive the click: <div class="priceFinderHeaderLogoWrap"></div>
this how the html code looks likes:
<span class="more">
<a onclick="setPID(27272);ta.fireEvent('hotels_lists_engagement_tracking.fired', {type: 'ReviewCount', element: this});ta.setEvtCookie('Reviews', 'ReviewCount', '1461750', 1, '/Hotel_Review');" target="_blank" href="/Hotel_Review-g150800-d1461750-Reviews-City_Express_Plus_Reforma_El_Angel-Mexico_City_Central_Mexico_and_Gulf_Coast.html#REVIEWS">254 opiniones</a></span>
my java code:
List<WebElement> links = driver.findElements(By.className("more"));
System.out.println(links.isEmpty());
for (int i = 0; i < links.size(); i++) {
links.get(i).click();
// do something in the web page...
}

Try this
List<WebElement> links = driver.findElements(By.XPath("//span[#class='more']/a"));

As per provided information, links are dynamic which is inside span with class as more. So in the code you tried
List<WebElement> links = driver.findElements(By.className("more"));
asking to load all span webelements but actually you need links right?
So if you need to load all links in particular span with class more then try like below
List<WebElement> links = driver.findElements(By.xpath("//span[#class='more']/a"));
provided that page contains unique span which you trying to get links.Then go for 'for' loop and click on link.
if you still get same issue, then use Actions to click on element. for example like below
for(int i=0; i<links.size(); i++){
new Actions(driver).moveToElement(links.get(i)).click().build().perform();
}
if your intention is to click on span as per code you tried then try Actions as above to get out of the exception.
Please make a note that there is chance of getting stealelement exception as you are performing click which may leads to page loads and driver loose its references to collected webelements in for loop.
Thank You,
Murali

Related

Picking a JavaScript button in HtmlUnit

In AliX, this page for example https://www.aliexpress.com/item/32956185908.html
how do you pick the particular country and colour?
For example, following js configure as country:
"skuPropertyValues":[
{"propertyValueDisplayName":"China","propertyValueId":201336100,"propertyValueIdLong":201336100,"propertyValueName":"China","skuPropertySendGoodsCountryCode":"CN","skuPropertyTips":"China","skuPropertyValueShowOrder":2,"skuPropertyValueTips":"China"},
{"propertyValueDisplayName":"GERMANY","propertyValueId":201336101,"propertyValueIdLong":201336101,"propertyValueName":"GERMANY","skuPropertySendGoodsCountryCode":"DE","skuPropertyTips":"GERMANY","skuPropertyValueShowOrder":2,"skuPropertyValueTips":"GERMANY"},
{"propertyValueDisplayName":"SPAIN","propertyValueId":201336104,"propertyValueIdLong":201336104,"propertyValueName":"SPAIN","skuPropertySendGoodsCountryCode":"ES","skuPropertyTips":"SPAIN","skuPropertyValueShowOrder":2,"skuPropertyValueTips":"SPAIN"},
{"propertyValueDisplayName":"Russian Federation","propertyValueId":201336103,"propertyValueIdLong":201336103,"propertyValueName":"Russian Federation","skuPropertySendGoodsCountryCode":"RU","skuPropertyTips":"Russian Federation","skuPropertyValueShowOrder":2,"skuPropertyValueTips":"Russian Federation"}]},
I'm not sure how to pick one through JavaScript or am I looing at the wrong thing, would it CS and picking up a div tag?
You have to enable js support and wait after retrieving the page until all the javascript is done. The js code will generate div's from you code above (use page.asXML() to get an idea of the page fro the viewpoint of HtmlUnit.
If the div's are there you can click() on them - like on any other html element. This click should trigger the same js code like in real browsers.
To find the div elements please have a look at https://htmlunit.sourceforge.io/gettingStarted.html; there are many different options listed.
Like #RBRi said, use the click method on the element. To choose the element (DIV in this case) you can use the getbyxpath method:
Starting from the page you can access using the XPATH of the element. The XPATH can be easily obtained using the browser inspect tool and copying the full XPATH of the div (right click over the div and use the copy option). For the purpose of your URL, "CHINA" element has the XPATH: /html/body/div[6]/div/div[2]/div/div[2]/div[7]/div/div[1]/ul/li[1]/div/ "GERMANY": /html/body/div[6]/div/div[2]/div/div[2]/div[7]/div/div[1]/ul/li[2]/div/span
page1 = webClient.getPage("https://www.aliexpress.com/item/32956185908.html");
// get china div using xpath
element = ((HtmlElement)page1.getByXPath("/html/body/div[6]/div/div[2]/div/div[2]/div[7]/div/div[1]/ul/li[1]/div/").get(0));
// Click over china
element.click();
webClient.waitForBackgroundJavaScript(10000);
If you want to iterate over the list of countries you can use the same approach, but this time copy the XPATH of the div that contains all the countries, get that element, and from this element then iterate by getting the divs. In this case, you can use the attribute "class" to get those elements:
page1 = webClient.getPage("https://www.aliexpress.com/item/32956185908.html");
element = ((HtmlElement)page1.getByXPath("/html/body/div[6]/div/div[2]/div/div[2]/div[7]/div/div[1]/ul").get(0); // Get the div that contains all countries
List<HtmlElement> elements = element.getElementsByAttribute("div", "class", "sku-property-text");
Then you can iterate over the list of elements and click the one you prefer.
:
choosenElement.click();
:

How can we find all links in a website other than home page using java selenium

I want to get all links with its response code in a website other than home page. I have tried using findElements method with anchor tag but this gives me links on home page only. Now suppose i have some menus also in that home page and i want to get links associated with that pages also. Is it possible??
Using this you can collect links from a page.
List<WebElement> aTags = driver.findElements(By.tagName("a");
List<String> links = new ArrayList<String>();
for (WebElement aTag: aTags) {
links.add(aTag.getAttribute("href");
}
For all links they are not file links, you can loop this as well.
Another thing is to check the response code, see https://www.baeldung.com/java-http-request.
To get all active links present in webpage please try below code. If possible please share your test URL and code, then I can replicate it from my side.
List<WebElement> linksList = driver.findElements(By.tagName("img"));
linksList.addAll(driver.findElements(By.tagName("a")));
System.out.println("The full size of Links and Images are: "+linksList.size());
List<WebElement> activeLinks = new ArrayList<WebElement>();
for(int i=0; i<linksList.size(); i++) {
Thread.sleep(200);
System.out.println(linksList.get(i).getAttribute("href"));
if(linksList.get(i).getAttribute("href") != null) {
activeLinks.add(linksList.get(i));
}
}

Child elements not found in page object after adding them in the html in Selenium

I have in my program a loop that prints a structure like this in each iteration:
<div class="grand-father">
<div class = "father">
<myTag>1</myTag>
<button>show more</button>
</div>
</div>
But after clicking the button the structure changes to:
<div class="grand-father">
<div class = "father">
<myTag>1</myTag>
<myTag>2</myTag>
<myTag>3</myTag>
</div>
</div>
So in my tests with page object model I'm trying to evaluate every myTag element in each "grand-father" element by doing:
List<WebElement> grandFathers = driver.findElements(By.xpath("//div[#class='grand-father']"));
for(WebElement gf : grandFathers){
//**Click the button of this father element to show more**
List<WebElement> myTagElements = gf.findElements(By.xpath(".//div[#class='father']/myTag"));
System.out.println(myTagElements.size());
}
My problem is that the last findElements for the myTag elements doesn't seem to be finding all the elements that weren't there before the "show more" button was pressed :( it's only counting one element even though all elements are already shown :/
Is there any way to tell selenium to "update" the variable according to the new html changes that weren't there when we first fetched the element? (Because I think that the problem might be that one)
Thanks if anyone can help!
It looks like you may have the answer already but for future readers, I would do something like this...
Grab all the DIVs with the class grand-father and loop through them looking for child BUTTONs. Click the BUTTON and then count the myTags.
List<WebElement> gfs = driver.findElements(By.cssSelector("div.grand-father"));
for (WebElement gf : gfs)
{
gf.findElement(By.tagName("button")).click();
System.out.println(gf.findElements(By.tagName("myTag")).size());
}
I solved the issue by refactoring all the code and clicking the "Show More" button when using findElements for the "father" elements, waay before using the findElements method for the myTag elements.
Keep this in mind when dealing with elements that will eventually show up in your DOM: First make all the operations that involve showing and processing data, then use Selenium to evaluate them :)

Selenium Webdriver - Find dynamic id from li/a

I am trying to select a value(Bellevue) from a li(it looks like a dropdown but it isn't).The problem is that its id changes everytime the page loads.
Here is a screenshot:
This time the id is: ui-id-23,but the number,23,will be changed next time so this will not work.If I expand the <a id="ui-id-23..." I get the name 'Bellevue' but every character surrounded by < strong > < /strong > mark-up.
I can't find it after it's classname because both values from li have the same class,ui-menu-item.
I tried after xpath:"//a[contains(text(),'Bellevue')]" but I get the error:Unable to locate element...
Do you know any solution for this?I am using Selenium Webdriver in Java and TestNG.
Thanks!
Update
So I managed to find that element by using:
WebElement value = driver.findElements(By.cssSelector("a[id^='ui-id-']")).get(3);
value.click(); .
but in my application i am using page objects and i look after elements using #FindBy(how.HOW.....).Do you know how I can use .get(3) with #FindBy?
You want to use a CSS selector on the ID:
a[id^='ui-id-']
This says "Find all of the a elements that have an ID that start with ui-id-"
If you want to find the second item, then do:
driver.findElements(By.cssSelector("a[id^='ui-id-']"))[1]
The [1] will select the second item on the page.
It looks like jQuery uniquId() method is used to populated the id, so it will always start with ui-id-. You can use jQuery selector to select element whose id starts with ui-id-
WebElement webElement = (WebElement) ((JavascriptExecutor) webDriver).executeScript("return $( 'input[id^="ui-id-"]').get(0);");
I would try to use xpath avoiding using of id. For example, //a[#class=''ui-corner-all ui-state-focus ][2]
First get the tag name in which your id attribute has been defined.
WebElement ele = driver.findElement(By.tagName(tagName));
String strId = ele.getAttribute("id").startsWith("ui-id-");
driver.findElement(By.id(strId)).click();

Selenium webdriver: How can I click these links?

<a onclick="requestReportGeneration('857f23e1baa767622a91f970963d8918', 'reportDiv31','CSV')" href="javascript:void[0];">CSV</a>
<a onclick="requestReportGeneration('64107e36323e5877c986edc98a17b6e8', 'reportDiv32','CSV')" href="javascript:void[0];">CSV</a>
<a onclick="requestReportGeneration('2cad4d4e5c8855c47a88b6ddf8345735', 'reportDiv33','CSV')" href="javascript:void[0];">CSV</a>
I have these three links on a page and I want to click each one in turn. I am reading all the links on the page into a list of WebElements and then I go through each one in turn if the href contains javascript:void[0] I then try to click it:
for (int i = 0; i < allLinks.size(); i++) {
String reportLink = allLinks.get(i).getAttribute("href");
if (reportLink.contains("javascript:void[0];"))
{
allLinks.get(i).click();
/// Do some more stuff
}
The problem is I keep getting an error saying the element is not visible. I have also tried just loading the page and instead of getting all the links doing
driver.findElement(By.xpath("//a[contains(#href,\"javascript:void[0]\")]")).click();
but that also just gives element not visible error.
Can anybody tell me why this isn't working?
Try putting a breakpoint before the while loop, debug your script, then step into it and use Eclipse's Display tab to interrogate what is up with the links. Try evaluating sample statements like:
allLinks.size();
allLinks.get(i).isDisplayed();
allLinks.get(i).isEnabled();
There must be something odd about the links (or the way webdriver is seeing them), but debugging like this will let you find out what it is.

Categories