jagdpanzer
jagdpanzer

Reputation: 713

xpath acts as though it clicks the button, but no real action is made

I am currently working on an automation test suite for a web application. The web application is really finicky. Recently, we had a UI update, so I ran tests to test out our GUI and buttons, as well as to access that our xpaths were still working.

THE NIGHT BEFORE HALLOWEEN, MY SCRIPT GOT REAL SPOOOOOOOKY~

Ghosts probably in my script

In these suites, I have a set of two tests: yesLogout, noLogout. yesLogout clicks the "Yes" button when you try to logout. noLogout clicks the "No" button when you try to logout.

When you run noLogout in the test script, the script clicks "No" and the logout prompt goes away.

When you run yesLogout in the test script, the script clicks the "Yes" button, but nothing happens. The "Yes" button makes an animation as though it was clicked, but the prompt just remains there.

Manually clicking the button works just fine.

I'm going to share the two methods (noLogout, yesLogout) as they are practically the same, they just call two different xpaths. For the sake of this question, forget that I'm testing at all - tests aren't the problem right now. Pretend I'm some weirdo who just really needs my script to click this button.

Two functions for use in tests (extremely simplified):

public class HiStackOverflow {

    public class yesLogout {
        public static void run(WebDriver driver) throws FileNotFoundException {
            Properties prop = new Properties();
            InputStream selectproductsidebar;

            selectproductsidebar = new FileInputStream(
                "C:/PATH/TO/PROPERTIES");
            try {
                prop.load(selectproductsidebar);
            } catch (IOException e) {
                e.printStackTrace();
            }


            WebElement yesLogout = driver.findElement(By.xpath(prop.getProperty("yeslogout")));
            Actions actions = new Actions(driver);
            actions.moveToElement(yesLogout).build().perform();
            yesLogout.click();
        }
    }

    public class noLogout {
        public static void run(WebDriver driver) throws FileNotFoundException {
            Properties prop = new Properties();
            InputStream selectproductsidebar;

            selectproductsidebar = new FileInputStream(
                "C:/PATH/TO/PROPERTIES");
            try {
                prop.load(selectproductsidebar);
            } catch (IOException e) {
                e.printStackTrace();
            }


            WebElement noLogout = driver.findElement(By.xpath(prop.getProperty("nologout")));
            Actions actions = new Actions(driver);
            actions.moveToElement(noLogout).build().perform();
            noLogout.click();
        }

    }
}

The xpath of the Yes button and the No button in the properties file:

yeslogout = //div[contains(@title,'Enter')]
nologout = //div[contains(@title,'Esc')]

And here is the HTML that relates to the issue:

<div style="transform: translate(0px, 60px) scale(1, 1) rotate(0deg);">
  <div style="transform: translate(10px, 0px) scale(1, 1) rotate(0deg);">
    <div>
      <div tabindex="6" role="button" aria-label="Yes" title="Keyboard shortcut: Enter">
        <div>
        </div>
        <div tabindex="7" role="button" aria-label="No" title="Keyboard shortcut: Esc" style="transform: translate(163.5px, 0px) scale(1, 1) rotate(0deg);">
          <div>
          </div>
        </div>
      </div>
    </div>

tabindex="6" is the yes button. tabindex="7" is the no button. There's a small difference in the two (the no button has some sort of transform: translate magic attached to it), but as far as I'm concerned it shouldn't be acting so strange.

Once again, the actual problem - running the yesLogout method locates, hovers over, and clicks the Yes button, but nothing happens. Manually clicking the yes button works out fine.

I can expand some more <div>s in the html if needed, but I really don't think it will show too much (just some more formatting and <canvas> stuff). I'm really interested in an explanation of what is going on. Thanks in advance.

EDIT: I have attempted to use JavascriptExecutor to click on the element, but alas, it did not work. This has been racking my brain all weekend.

Even doing crazy stuff like:

WebElement yesLogout = driver.findElement(By.xpath(prop.getProperty("yeslogout")));
        Actions actions = new Actions(driver);
        actions.moveToElement(yesLogout, 10, 10).build().perform();
        yesLogout.click();
        yesLogout.click();
        yesLogout.click();
        yesLogout.click();
        yesLogout.click();
        yesLogout.click();

Shows the button being clicked over and over and over again, but no actual functionality.

For the sake of completeness and trying to get people to understand the issue, I'll restate, manually clicking the button works wonderfully. As does the Enter shortcut. Selenium .click() commands VISIBLY "work", but do not carry out the functionality of the button itself.

SECOND EDIT: I will include a fully expanded HTML of the concerning divs:

<div style="transform: translate(794px, 202px) scale(1, 1) rotate(0deg);" tabindex="5" role="dialog">
  <div>
    <div>
      <div>
        <div>
          <div>
            <canvas height="106" width="332" style="top: 0px; left: 0px; width: 332px; height: 106px;" />
          </div>
        </div>
        <div style="transform: translate(10px, 10px) scale(1, 1) rotate(0deg);">
          <div>
            <div style="transform: translate(6px, 6px) scale(1, 1) rotate(0deg);">
              <div style="font-family: franklin-gothic-urw; font-weight: 400; font-style: normal; font-size: 14px; opacity: 1; color: rgb(0, 0, 0);">Are you sure you want to logoff?</div>
            </div>
          </div>
        </div>
        <div style="transform: translate(0px, 60px) scale(1, 1) rotate(0deg);">
          <div style="transform: translate(10px, 0px) scale(1, 1) rotate(0deg);">
            <div>
              <div tabindex="6" role="button" aria-label="Yes" title="Keyboard shortcut: Enter">
                <div>
                  <div>
                    <div>
                      <div>
                        <div>
                          <canvas height="36" width="148" style="top: 0px; left: 0px; width: 148.5px; height: 36px;" />
                        </div>
                      </div>
                      <div style="transform: translate(56px, 7px) scale(1, 1) rotate(0deg);">
                        <div style="font-family: proxima-nova; font-weight: 400; font-style: normal; font-size: 17px; opacity: 1; color: rgb(255, 255, 255); transform: translate(5px, 0px) scale(1, 1) rotate(0deg);">Yes</div>
                      </div>
                      <div style="">
                        <div>
                          <div>
                            <canvas height="36" width="148" style="top: 0px; left: 0px; width: 148.5px; height: 36px;" />
                          </div>
                        </div>
                        <div style="display: none;">
                          <div>
                            <canvas height="36" width="148" style="top: 0px; left: 0px; width: 148.5px; height: 36px;" />
                          </div>
                          <div style="transform: translate(56px, 7px) scale(1, 1) rotate(0deg);">
                            <div style="font-family: proxima-nova; font-weight: 400; font-style: normal; font-size: 17px; opacity: 1; color: rgb(255, 255, 255); transform: translate(5px, 0px) scale(1, 1) rotate(0deg);">Yes</div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <div tabindex="7" role="button" aria-label="No" title="Keyboard shortcut: Esc" style="transform: translate(163.5px, 0px) scale(1, 1) rotate(0deg);">
                <div>
                  <div>
                    <div>
                      <div>
                        <div>
                          <canvas height="36" width="148" style="top: 0px; left: 0px; width: 148.5px; height: 36px;" />
                        </div>
                      </div>
                      <div style="transform: translate(58px, 7px) scale(1, 1) rotate(0deg);">
                        <div style="font-family: proxima-nova; font-weight: 400; font-style: normal; font-size: 17px; opacity: 1; color: rgb(255, 255, 255); transform: translate(5px, 0px) scale(1, 1) rotate(0deg);">No</div>
                      </div>
                      <div style="display: none;">
                        <div>
                          <div>
                            <canvas height="36" width="148" style="top: 0px; left: 0px; width: 148.5px; height: 36px;" />
                          </div>
                        </div>
                        <div style="display: none;">
                          <div>
                            <canvas height="36" width="148" style="top: 0px; left: 0px; width: 148.5px; height: 36px;" />
                          </div>
                          <div style="transform: translate(58px, 7px) scale(1, 1) rotate(0deg);">
                            <div style="font-family: proxima-nova; font-weight: 400; font-style: normal; font-size: 17px; opacity: 1; color: rgb(255, 255, 255); transform: translate(5px, 0px) scale(1, 1) rotate(0deg);">No</div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Upvotes: 2

Views: 1995

Answers (3)

James Brierley
James Brierley

Reputation: 4670

There are a few things that might cause this, but I couldn't be certain without you adding the relevant JavaScript to your question. I'm assuming that somewhere in the JavaScript on your page, there is a function bound to the click event that is actually performing the action you are expecting.

It could be that this event is bound to a child of the yes button. In this case, clicking on the button on the page might trigger the click event when done so in a browser. However because your xpath is targeting the parent, selenium will only trigger a click event against that element, and would therefore not trigger any events on its children. However, the animation might still be triggered if it is attached to the parent. This could be fixed by making the xpath target the specific element that has the click event attached to it.

Unfortunately, finding which element the event is attached to could be a pain if the JavaScript is a mess. One thing that might help you, is that if you inspect an element in Chrome developer tools, there is an event listeners tab. You can see which elements have click events bound to them, but this won't show the specific method if they are using jQuery, and instead one of the jQuery methods.

Upvotes: 1

makeMonday
makeMonday

Reputation: 2415

I don't know if it is up to you or not, but I would try to add an id or a more distinctive property for these buttons (since they are important for the application).

On the other hand, do you necessarily need the actions.moveToElement() thing? Can't you just click the element? This could decrease any unexpected behaviors:

WebElement yesLogout = driver.findElement(By.xpath("..."));
yesLogout.click();

One last thing (for a better understanding), I am not sure I understand why would you use a div as a button? Why is the No button, inside the (div) Yes button? This could lead to an issue.

Upvotes: 1

Syed
Syed

Reputation: 187

Try debugging using different options first such as pass keyboard Enter key to see if it works

WebElement.sendKeys(Keys.ENTER);

Other options you can try is using CSS to find the element or Java script methods to click the element

WebElement element = driver.findElement(By.id("gbqfd"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);

reference: How to click an element in Selenium WebDriver using JavaScript

Upvotes: 2

Related Questions