Unable to click one by one present in image carousel with selenium - java

I am unable to click on the images present in below carousel as shown in below snapshot. I tried a lot but failed though i was able to navigate to other images by clicking on the right Arrow navigation button . The Image Carousel is Present below the Featured Vehicles header Text (in website) which has navigation buttons both left and right.
Site Link : https://ryder.com/used-trucks
Below is the one of the approach that I tried ,and the code is below. Please i need your help on this at the earliest.
public void click_Image_Carousel_To_Open_ProductDetailsPage() throws InterruptedException
{
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].scrollIntoView();", driver.findElement(By.xpath("//h2[contains(text(),'FEATURED VEHICLES')]")));
WebElement ele1= null;
String image_link = null;
List<WebElement> image_Carousel_Links_list = driver.findElements(By.xpath("(//div[#class='photo']/a)"));
System.out.println("Size :"+image_Carousel_Links_list.size());
WebElement image_Carousel_Next_Btn = driver.findElement(By.xpath("//BUTTON[#class='slick-next slick-arrow'][text()='Next']"));
for(int i=1;i<image_Carousel_Links_list.size();i++)
{
System.out.println(+i+")Image links :"+driver.findElement(By.xpath("(//div[#class='photo']/a)["+i+"]")).getAttribute("href"));
System.out.println(" Element : (//div[#class='photo']/a)["+i+"]");
ele1=driver.findElement(By.xpath("(//div[#class='photo']/a)["+i+"]"));
//this for loop to rediscover the elements to avoid stale element exception
for(int k=0;k<500;k++)
{
image_Carousel_Links_list = driver.findElements(By.xpath("(//div[#class='photo']/a)"));
if(driver.findElement(By.xpath("(//div[#class='photo']/a)["+i+"]")).isDisplayed())
{
ele1=driver.findElement(By.xpath("(//div[#class='photo']/a)["+i+"]"));
break;
}
click_ImageCarousel_NextButton(image_Carousel_Next_Btn);
Thread.sleep(300);
}
if(ele1.isDisplayed())
{
ele1.click();
System.out.println(i+") Clicked on the Image present in Image Carousel :" +ele1.getAttribute("href"));
Thread.sleep(3000);
driver.navigate().back();
Thread.sleep(4000);
}
else
{
System.out.println(" Image Not found in Image Carousel");
}
}
}
private void click_ImageCarousel_NextButton(WebElement image_Carousel_Next_Btn) {
image_Carousel_Next_Btn.click();
}

Related

org.openqa.selenium.StaleElementReferenceException: element is not attached to the page document

I am trying to test the GeeksForGeeks UI. When I click the tutorials dropdown, then select languages and select Java, it links to a new page and the following error occurs org.openqa.selenium.StaleElementReferenceException. How can I solve this issue? I have tried all the possible solutions from stackoverflow.
public class SeleniumTest {
public static WebDriver driver;
#BeforeClass
public static void setupClass() {
System.setProperty("webdriver.chrome.driver", "driver/chromedriver.exe");
}
#Before
public void setup() {
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
}
#After
public void after() {
driver.close();
}
#Test
public void testGeeksForGeeksR() throws InterruptedException {
driver.get("https://www.geeksforgeeks.org/");
WebElement tutorialsMenu = driver.findElement(By.className("header-main__list-item"));
tutorialsMenu.click();
List<WebElement> tutorialsList = tutorialsMenu.findElements(By.tagName("li"));
for (WebElement li : tutorialsList) {
if (li.getText().equals("Languages")) {
li.click();
List<WebElement> languages = driver.findElements(By.tagName("a"));
for (WebElement a : languages) {
if (a.getText().equals("Java")) {
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.elementToBeClickable(a));
a.click();
WebElement title = driver.findElement(By.className("entry-title"));
assertEquals("Java Programming Language", title.getText());
}
}
}
}
Thread.sleep(6000);
}
}
Solution:
#Test
public void testGeeksForGeeksR() throws InterruptedException {
driver.get("https://www.geeksforgeeks.org/");
WebElement tutorialsMenu = driver.findElement(By.className("header-main__list-item"));
tutorialsMenu.click();
List<WebElement> tutorialsList = tutorialsMenu.findElements(By.tagName("li"));
WebElement javaLanguage = null;
for (WebElement li : tutorialsList) {
if (li.getText().equals("Languages")) {
li.click();
List<WebElement> languages = driver.findElements(By.tagName("a"));
for (WebElement a : languages) {
if (a.getText().equals("Java")) {
javaLanguage = a;
break;
}
}
}
}
javaLanguage.click();
driver.switchTo().activeElement();
WebElement title = driver.findElement(By.className("entry-title"));
assertEquals("Java Programming Language", title.getText());
Thread.sleep(3000);
}
After clicking on the a element with Java text the Java Programming Language page is opened.
At this point all the element references collected on the previous page are becoming Stale.
Generally, each Selenium WebElement object is actually a reference (pointer) to physical web element object.
So, when you are opening another web page or refreshing the existing page (reloading the web elements there) all the references to the web elements on the previous web page are no more valid.
In the Selenium terminology this situation is called Stale Element.
Getting back to your specific code flow.
Looks like your target here is to open the Java Programming Language page. If so, all what you are missing here is to exit your loop once that page is opened and finish the test.
In case you wish to continue opening another tutorials from the menu on the main page you will have to go back from the internal page you opened and then get all the elements you wish to use there again.

Opening a new tab and trying to scroll down the page and clicking on a link fails in Firefox browser

I have this function where I am trying to scroll down the page and click on a link. I have put the code in a for loop because I want to open more than one tab.
The links which I am trying to click are out of view of the window and they are in footer which is common for all the web pages. My method is supposed to scroll down till the link to be clicked is visible and then control + click and open a new tab. The method works perfectly well in Chrome and Internet Explorer browsers but fails in Firefox saying that the link to be clicked is not present. I think it is not scrolling down despite my putting code to scroll down. Please help.
public static void checkHrefsWithBrowserUrls(List<WebElement> links)
{
String parentTab = null;
String clickOnLink = Keys.chord(Keys.CONTROL, Keys.ENTER);
log.debug("Checking that the links open the correct url");
for (WebElement link : links) {
((JavascriptExecutor)driver)
.executeScript("arguments[0].scrollIntoView(true);", link);
String href = link.getAttribute("href");
link.sendKeys(clickOnLink);
WaitUtilities.sleep(1L);
Iterator<String> handleIterator = driver.getWindowHandles().iterator();
parentTab = handleIterator.next();
if(handleIterator.hasNext()) {
driver.switchTo().window(handleIterator.next());
WaitUtilities.waitForUrlToBe(url());
if(!href.equals(url())) {
log.error("Link(s) opening wrong URL(s): " + url());
}
driver.close();
driver.switchTo().window(parentTab);
}
}
driver.switchTo().window(parentTab);
}
Here is the pseudo code to handle the state element issue.
public static void checkHrefsWithBrowserUrls(String xpath)
{
String parentTab = null;
String clickOnLink = Keys.chord(Keys.CONTROL, Keys.ENTER);
log.debug("Checking that the links open the correct url");
int linksCount = driver.findElements(By.xpath(xpath)).size();
for (int linkCounter=1; linkCounter=linksCount, linkCounter++) {
link = driver.findElements(By.xpath(xpath)).get(linkCounter)
((JavascriptExecutor)driver)
.executeScript("arguments[0].scrollIntoView(true);", link);
String href = link.getAttribute("href");
link.sendKeys(clickOnLink);
WaitUtilities.sleep(1L);
Iterator<String> handleIterator = driver.getWindowHandles().iterator();
parentTab = handleIterator.next();
if(handleIterator.hasNext()) {
driver.switchTo().window(handleIterator.next());
WaitUtilities.waitForUrlToBe(url());
if(!href.equals(url())) {
log.error("Link(s) opening wrong URL(s): " + url());
}
driver.close();
driver.switchTo().window(parentTab);
}
}
driver.switchTo().window(parentTab);
}

Selenium WebDriver: Scroll custom scrollbar till it will reach up to desired element

I am trying to automate WhatsApp web application. The contacts div has a custom scrollbar. The group I have to post a message is not displayed on the web page and hence cannot be clicked. How can I scroll upto that perticular group? I have tried following code but it is not working.
#Test
void begin(){
openBrowser();
driver.get("https://web.whatsapp.com/");
sleep(10000);
WebElement scroll = driver.findElement(By.id("pane-side")); // locator of contacts div.
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", scroll);
//Thread.sleep(500);
//WebElement groupName = driver.findElement(By.xpath("//span[text()='Word of the day']")); //locator of group
}
A helper class for custom scroll bar:
public class ScrollHelper {
private static String VeticalScrollScript = "arguments[0].scrollTop = arguments[1]";
private static String HorizonScrollScript = "arguments[0].scrollLeft = arguments[1]";
private JavascriptExecutor jsExecutor;
public ScrollHelper() {
this.jsExecutor = (JavascriptExecutor) driver;
}
public ScrollHelper asHorizon(scrollTarget, scrollContext) {
if(isPresentHorizonScrollBar(scrollContext)) {
int offset = scrollTarget.getLocation().getX() -
scrollContext.getLocation().getX();
this.jsExecutor.executeScript(HorizonScrollScript, scrollContext, offset);
}
return this;
}
public ScrollHelper asVertical(scrollTarget, scrollContext) {
if(this.isPresentVerticalScrollBar(scrollContext)) {
int offset = scrollTarget.getLocation().getY() -
scrollContext.getLocation().getY();
this.jsExecutor.executeScript(VeticalScrollScript, scrollContext, offset);
}
return this;
}
private boolean isPresentHorizonScrollBar(WebElement scrollContext) {
String script = "return arguments[0].scrollWidth > arguments[0].clientWidth;";
return (Boolean) (this.jsExecutor.executeScript(script, scrollContext));
}
private boolean isPresentVerticalScrollBar(WebElement scrollContext) {
String script = "return arguments[0].scrollHeight > arguments[0].clientHeight;";
return (Boolean) (this.jsExecutor.executeScript(script, scrollContext));
}
}
For your case:
ScrollHelper scroll = new ScrollHelper(driver);
scroll.asVertical(
scrollTarget, // the group
scrollContext // the element who owns the custom scroll bar
);
In below case, the scrollContext is the pre highlighted by Green line,
Not its parent <div class="post-text"> or other element. You need to find out the correct element who owns the custom scroll bar as value for scrollContext.
A way to find the correct scrollContext is to see element has CSS style over-flow, if you uncheck the checkbox before over-flow, you will notice the scroll bar will disappear, and come back when check it.
Try something like this? (Tweak for your project!)
while (true) {
try {
WebElement backgroundDivInsideScrollingPane = driver.findElement(By.xpath("//div[#id='idOfAnElementInTheScrollingPane']"));
backgroundDivInsideScrollingPane.sendKeys(Keys.PAGE_DOWN);
WebElement elementToBeFound = driver.findElement(By.xpath("//myElementLocatorHere"));
break;
} catch (Exception ignored) {
// Exception because element can't be found yet - Ignore!
}
}
Whatsapp Messaging section with this code
You will be able to take the Page Down and the Page Up.
Note:
100% working :)
Message Detail Scroll Down and Scroll Up
private void SyhMhzScrollDetailPageUP()
{
IWebElement scroll = drv.FindElementByXPath("//div[#class='_1ays2']");
scroll.SendKeys(Keys.PageUp);
}
private void SyhMhzScrollDeatilPageDown()
{
IWebElement scroll = drv.FindElementByXPath("//div[#class='_1ays2']");
scroll.SendKeys(Keys.PageDown);
}
Message List Scroll Down and Scroll Up
private void SyhMhfzMesgListScrollPageUP()
{
IWebElement scroll = drv.FindElementByXPath("//div[#data-tab='4']");
scroll.SendKeys(Keys.Up);
}
private void SyhmhfzMesgListPageDown()
{
IWebElement scroll = drv.FindElementByXPath("//div[#data-tab='4']");
scroll.SendKeys(Keys.Down);
}
You can also use the Nuget package here.
https://www.nuget.org/packages/Bekra.Whatshapp_Scroll_Down_Up/1.0.0

Selenium : Automating LinkedIn - Profile Icon

I am new to Selenium and trying to use Actions class to mouseover on the Profile icon available on linked in site to open the menu that appears on Mouseover of profile image.
Below is my code and when it reaches on to those lines the error comes : Unable to locate element..
This is happening with all the icons available on Linked on top bar ( messages / Flag icon etc.
Code :
public class LinkedIn {
WebDriver driver = new FirefoxDriver();
#BeforeTest
public void setUp() throws Exception {
String baseUrl = "http://www.linkedin.com/";
driver.get(baseUrl);
}
#Test
public void login() throws InterruptedException
{
WebElement login = driver.findElement(By.id("login-email"));
login.sendKeys("*****#gmail.com");
WebElement pwd = driver.findElement(By.id("login-password"));
pwd.sendKeys("*****");
WebElement in = driver.findElement(By.name("submit"));
in.click();
Thread.sleep(10000);
}
#Test
public void profile() {
// here it gives error to me : Unable to locate element
Actions action = new Actions(driver);
WebElement profile = driver.findElement(By.xpath("//*[#id='img-defer-id-1-25469']"));
action.moveToElement(profile).build().perform();
driver.quit();
}
}
It seems you have used incorrect xpath , Kindly check below example to mouse hover on Message button :
Thread.sleep(5000);
Actions action = new Actions(driver);
WebElement profile = driver.findElement(By.xpath("//*[#id='account-nav']/ul/li[1]"));
action.moveToElement(profile).build().perform();
Correct Xpaths are :
For Message Icon : "//*[#id='account-nav']/ul/li[1]"
For Connection Icon : //*[#id='dropdowntest']
Above code I just tested and working fine so will work for you.

How to fetch all links and click those links one by one with Selenium WebDriver

I want to do the following:
I want to fetch and display all links on webpage.
After displaying, I want to click each link one by one.
I'm able to do point 1 using foreach loop but I'm not able to 2nd point.
Here is the code:
public class OpenAllLinks {
public static void main(String[] args) {
WebDriver driver=new FirefoxDriver();
driver.get("http://bing.com");
List<WebElement> demovar = driver.findElements(By.tagName("a"));
System.out.println(demovar.size());
for (WebElement var : demovar) {
System.out.println(var.getText()); // used to get text present between the anchor tags
System.out.println(var.getAttribute("href"));
}
for (WebElement var : demovar) {
var.click();
}
}
}
when the first link is clicked, the browser will load the respective page. hence the other links those you had captured in the first page wouldn't be available.
If the intent is to navigate to the every link's target, then store the target location and navigate to it, like this
driver.get("<some site>");
List<WebElement> links=driver.findElements(By.tagName("a"))
ArrayList<String> targets = new ArrayList<String>();
//collect targets locations
for (WebElement link : links) {
targets.add(link.getAttribute("href"));
}
for (WebElement target : targets) {
driver.get(target);
//do what is needed in the target
}
static WebDriver driver=null;
public static void main(String[] args) throws IOException
{ System.setProperty("webdriver.chrome.driver","D:\\softwaretesting\\broswer driver\\chromedriver.exe");
WebDriver driver = new ChromeDriver();``
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
//driver.manage().window().maximize();
driver.get("http://google.com/");
List<WebElement> links=driver.findElements(By.tagName("a"));
System.out.println("Total links are "+links.size());
for(int i=0;i<links.size();i++)
{
WebElement ele= links.get(i);
String url=ele.getAttribute("href");
verifyLinkActive(url);
}
}
public static void verifyLinkActive(String linkUrl)
{ try
{
URL url = new URL(linkUrl);
HttpURLConnection httpURLConnect=(HttpURLConnection)url.openConnection();
httpURLConnect.setConnectTimeout(3000);
httpURLConnect.connect();
if(httpURLConnect.getResponseCode()==200) {
System.out.println(linkUrl+" - "+httpURLConnect.getResponseMessage());
File src= (TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(src, new File("D://screenshort//Spiritualbridge//"+System.currentTimeMillis()+".png"));
} if(httpURLConnect.getResponseCode()==HttpURLConnection.HTTP_NOT_FOUND)
{
System.out.println(linkUrl+" - "+httpURLConnect.getResponseMessage() + " - "+ HttpURLConnection.HTTP_NOT_FOUND);
}
} catch (Exception e)
{
}
}
That happens because the link when clicked, navigates to a new page where it doesn't find the next element in your list to click. Please try the below code that will navigate to each link (I have used the code by #deepak above and have modified it accordingly as per your need):
WebDriver driver=new FirefoxDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://bing.com");
List<WebElement> demovar=driver.findElements(By.tagName("a"));
System.out.println(demovar.size());
ArrayList<String> hrefs = new ArrayList<String>(); //List for storing all href values for 'a' tag
for (WebElement var : demovar) {
System.out.println(var.getText()); // used to get text present between the anchor tags
System.out.println(var.getAttribute("href"));
hrefs.add(var.getAttribute("href"));
System.out.println("*************************************");
}
//Navigating to each link
int i=0;
for (String href : hrefs) {
driver.navigate().to(href);
System.out.println((++i)+": navigated to URL with href: "+href);
Thread.sleep(3000); // To check if the navigation is happening properly.
System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
}

Categories

Resources