gfk-ba / senbot

Cucumber / Selenium framework in Java
MIT License
10 stars 11 forks source link

synchronisationService.waitAndAssertForExpectedCondition does not sync correctly #6

Closed SchnuckySchuster closed 11 years ago

SchnuckySchuster commented 11 years ago
Feature:
  As a user 
  when synchronizinig on an event
  I want to be sure that I can execute the action I have synchronized on

Scenario:
   Given there is a button that is clickable
  When I synchronize on clickable on that element
    And the synchronisation has worked
  Then the click on the element shall also work

Example:

By locator = By.xpath("x.//div[@class='reportListItemTitle']/span[text()='-1906855377-New category']/parent::/preceding-sibling::/img); synchronisationService.waitAndAssertForExpectedCondition(ExpectedConditions.elementToBeClickable(locator)); Thread.sleep(5000); //<<<<< Only working with a sleep driver.findElement(locator).click();

nreijmersdal commented 11 years ago

I have a similar issue somewhere else. I think this happens when the element is found, but later its moved due to slow/weird browser rendering or CSS being applied later.

nreijmersdal commented 11 years ago

A possible solution is to record the location of the element when its found, then always wait 500 milliseconds (100 milliseconds was not enough in my case) to give it a chance to move around, then check its current location vs the old location and if the element moved, wait 500 milliseconds and check if it is still moving, repeat until it it stays in the same spot for 500 milliseconds.

See my example for details:

    @When("^I click on the \"([^\"]*)\" label$")
    public void I_click_on_the_label(String text) throws Throwable {
        Point locationOne = null;
        WebElement labelElement = null;
        By by = By.xpath("//label[text()='" + text + "']");

        // Make sure atleast one element exists in the DOM
        WebDriverWait wait = new WebDriverWait(driver, 30);
        wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(by));

        // Retrieve a list of all the elements
        // Set the first one that is visible as the element to use
        List<WebElement> elements = driver.findElements(by);
        Iterator<WebElement> iterator = elements.iterator();
        while(iterator.hasNext()) {
            WebElement element = iterator.next();
            if(element.isDisplayed()) {
                locationOne = element.getLocation();
                labelElement = element;
            }
        }

        if(labelElement != null) {
           Thread.sleep(500); // Give the object a chance to move, or else locations are always the same
           Point locationTwo = labelElement.getLocation();
           while(locationOne.getX() != locationTwo.getX() || locationOne.getY() != locationTwo.getY()) {
               System.out.println("Location of label " + text + ", location was " + locationOne.toString() + " location now is " + locationTwo.toString());
               locationTwo = labelElement.getLocation();
               Thread.sleep(500); // Wait for the element to stop moving
               locationOne = labelElement.getLocation();
           }
           labelElement.click();   
        } else {
            fail("No label found with the text: " + text);
        }
    }
nreijmersdal commented 11 years ago

From the original post its impossible to conclude how to reproduce the issue, closing it for this reason.