0
votes

I am getting a very long xpath for an element that I selected. Is there anyway to shorten it? This is the xpath I am getting:

//li[@class='menu_men 1-level hasChild']//div[contains(@class,'level-2')]//div[@class='menu-wrapper']//ul[@class='level-2']//li[@class='1-level']//div[@class='level-3']//ul[@class='level-3']//li//a[@class='level-3'][contains(text(),'Socks')]

This is the URL: Calvin Klein Singapore I hovered over 'MEN', the accessories section will appear, than I hover the 'Socks' to get the xPath.

I am getting the following execption in my code and I am wondering if somehow the long xpath could be one of the reasons:

org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//li[@class='first menu_men 1-level hasChild']//div[contains(@class,'level-2')]//div[@class='menu-wrapper']//ul[@class='level-2']//li[@class='1-level']//div[@class='level-3']//ul[@class='level-3']//li//a[@class='level-3'][contains(text(),'Socks')]"}

I am using cropath from within chrome developer tools to get the xPath.

I am new to automation, I really hope someone can advise. Thank you.

@SameerArora this is the code I have to clear the pop up window, as what I had mentioned in the comments below.

//for clearing the popup window
    @FindBy(how=How.XPATH,using="//*[starts-with(@id,'popup-subcription-closes-link-')]")
    public WebElement newsletterpopup;  

    public String clickCategory(){
                //.....
                resusableFunctions.buttonClick(driver, newsletterpopup, "popoup");
                }
    public void buttonClick(WebDriver driver, WebElement element, String elementName) throws InterruptedException
        {
            try
            {
                element.click();
                System.out.println("Log: ResuableFunction.buttonClick");
            }
        catch (org.openqa.selenium.ElementNotInteractableException notInteract)
            {}
4

4 Answers

1
votes

The element you are looking for can be found using xpath:

WebElement element = driver.findElement(By.xpath("(//a[contains(text(),'Socks')])[1]"));

However, as the element is not visible directly when you are opening the link, you would be getting NoSuchElementException, so to resolve it you can use javascript click method on the element which directly operates on the div of the page.
Addition to this, i can see that a subscription popup comes when i am opening the page for the first time, so you need to dismiss that popup first(if the popup is present) and then click on the "Socks" element using the JavaScript click method.

Your code should be like:

List<WebElement> closeSubscriptionPopUp = driver.findElements(By.xpath("//a[contains(@id,'popup-subcription-closes-link')]"));
if (closeSubscriptionPopUp.size() > 0) {
    closeSubscriptionPopUp.get(0).click();
}
WebElement sockElement = driver.findElement(By.xpath("(//a[contains(text(),'Socks')])[1]"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", sockElement);
1
votes

To hovered over 'MEN' >> accessories >> 'Socks' section, You need to use selenium Actions class.

As it is not really possible to first click on men(as it will open other section), So to hover to sock, you need to chain all of the actions that you want to achieve in one go.

Process should be:

  1. move to men element first
  2. Move to accessories
  3. then move to Socks and click on it.

Note: By using Action class, we can chain all the process in one single go. As mentioned below

1) First way:

Actions action = new Actions(driver);
action.moveToElement(driver.findElement(By.xpath("(//a[contains(text(),'MEN')])[2]")))
.moveToElement(driver.findElement(By.xpath("(//a[contains(text(),'Socks')])[1]")))
.click().build().perform();

2) Second way with wait:

WebDriverWait wait= new WebDriverWait(driver, 10);
Actions action = new Actions(driver);
action.moveToElement(driver.findElement(By.xpath("(//a[contains(text(),'MEN')])[2]"))).build().perform();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("(//a[contains(text(),'Socks')])[1]")));
action.moveToElement(driver.findElement(By.xpath("(//a[contains(text(),'Socks')])[1]")));
action.click().build().perform();
0
votes

Try this:

//a[normalize-space(text()) = 'Socks']

I would recommend you to not use such long xpath's and try to write xpath on your own.

-1
votes

Try :

//li[contains(@class,'menu_men')]//a[contains(text(),'Socks')]