5

I'm developing Selenium tests in java, and i'm looking for a solution for my problem. I want to click on a zone ( coordinates ) of an element during the test. This click implicitly returns me the Xpath of the clicked element present in this zone, in order to compare this Xpath in a second time.

Why i want to compare this Xpath ?

I want to check if this Xpath is the one of the element supposed to be displayed on the screen. For example, when i change the css of my web page, a button can be hidden by a div or wathever. So i want my test to click on the zone of that button, get the Xpath of the element present in this zone, and check if it's the Xpath of my button !

I have already find solution to click on a specific coordinates, but it's always depending of the element.

I have also already developed this solution in Javascript using this :

 if (driver instanceof JavascriptExecutor) {
              ((JavascriptExecutor)driver).executeScript("MY SCRIPT");
          } else {
              throw new IllegalStateException("This driver does not support JavaScript!");
          }

I can integrate the script in my Java Selenium test but i can't find a way to get the returning Xpath value in a Java variable.

Thanks for helping guys !

============ SOLVED ================

I solved my problem. For those who having the same issue, here is my solution : In my Selenium Test in Java, I created a method that includes Javascript :

    public void IsHiddenByOtherElement(WebDriver driver, String xpath, int CordX, int CordY) throws IOException
      {  

              if (driver instanceof JavascriptExecutor) 
              {
                        String script = "setTimeout(function() "
                        + "{jQuery(document.elementFromPoint("+CordX+", "+CordY+")).click();}, 0.1);"
                        + "elementClicked = document.elementFromPoint("+CordX+", "+CordY+");"
                        + "var value2 = "+xpath+";"
                        + "var id = elementClicked.id;$( '#' + id ).click(function() "
                        + "{ "
                        + "var value=xpath(this); "
                        + "if (value!=value2) throw new Error(value + ' : Element cache sous un autre : '+ value2);"
                        + "});"
                        + "function xpath(el) "
                        + "{"
                        + "if (typeof el == 'string') return document.evaluate(el, document, null, 0, null);"
                        + "if (!el || el.nodeType != 1) return '';"
                        + "if (el.id) return '//*[@id=' + el.id + ']';var sames = [].filter.call(el.parentNode.children, "
                        + "function (x) { "
                        + "return x.tagName == el.tagName });"
                        + "return xpath(el.parentNode) + '/' + el.tagName.toLowerCase() + (sames.length > 1 ? '['+([].indexOf.call(sames, el)+1)+']' : '');"
                        + "}";

              ((JavascriptExecutor) driver).executeScript(script); 

              } 
              else 
              {
                  throw new IllegalStateException("This driver does not support JavaScript!");
              }
              final List jsErrors = JavaScriptError.readErrors(driver);
              assertTrue(jsErrors.toString(), jsErrors.isEmpty());
      }

This method simulate the click in specific coordinates, recovers the Xpath of that element, and compare it to the Xpath of the element that is supposed to be displayed on screen. If the comparison isn't successful, it generate a JavaScript errors. This method is also configured to listen this JavaScript errors and to stop the test if one occurs, and returns it as any classic Selenium Java errors

The String script is the Javascript comparison test.

There is also :

       final List jsErrors = JavaScriptError.readErrors(driver);
       assertTrue(jsErrors.toString(), jsErrors.isEmpty());

This 2 lines are here to listen JavaScript errors and stop the running test if one happens.

To finish, you just need to had

       FirefoxProfile ffProfile = new FirefoxProfile();
       JavaScriptError.addExtension(ffProfile);
       final WebDriver driver = new FirefoxDriver(ffProfile);
       driver.get("file:///Users/Max/Downloads/elementfrompoint.html");
       IsHidden(driver,"'//*[@id=test]'",50,50);

And here it is !

Thanks for help

sinsuren
  • 1,745
  • 2
  • 23
  • 26
MxfrdA
  • 171
  • 3
  • 14
  • 1
    IMHO you are heading for disaster. If you write tests that rely on elements to be present at certain screen coordinates, then those tests will never work reliably. Your UI elements might move around for many reasons: screen resolution, aspect ratio, font size, new UI elements, etc. If you want to make sure that an UI element is visible, select it via XPath or CSS selectors and then test whether it is visible/clickable – Ralf Mar 16 '16 at 08:39
  • Thanks for reply ! Of course, if I do this, it will be in a specific resolution. But i haven't thought of the " clickable " option. How can I use it ? – MxfrdA Mar 16 '16 at 08:42
  • `WebElement::click()` will throw an error if the element is not clickable (not visible or not on the top display layer). There are lots of threads about this. E.g. [this one](http://stackoverflow.com/questions/9878478/selenium-webdriver-determine-if-element-is-clickable-i-e-not-obscured-by-doj). – Ralf Mar 16 '16 at 08:51
  • The clickable test pass even when, for example, a button is hidden by a div. I have to search for an other solution. It's weird, because when i do the test by hand, i configure my button to alert something on click, and when the div hides the button, the alert doesn't pop-up, so the element isn't clikable at all ! – MxfrdA Mar 16 '16 at 09:58
  • You can also check for visibility. – Ralf Mar 16 '16 at 10:33
  • Yes, but visibility check the display and none elements. In my case it's just hidden. I think in going integrate my js script in my java, and find a way to listen js errors to stop my selenium test – MxfrdA Mar 16 '16 at 10:56
  • 1
    If solved, please, post the answer (repeat from comments, if possible) and mark it. Otherwise it will be hanging on the list of unanswered questions for ages. – Honza Hejzl Apr 22 '16 at 06:15
  • Already done, mark as Solved and the question has been edited – MxfrdA Apr 22 '16 at 08:26

0 Answers0