Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to wait until selenium web element animation is ended #7659

Merged
merged 1 commit into from
Nov 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public class ProjectExplorer {
private final NavigateToFile navigateToFile;
private final Menu menu;
private final CodenvyEditor editor;
private final TestWebElementRenderChecker testWebElementRenderChecker;
private WebDriverWait loadPageTimeout;
private WebDriverWait redrawUiElementsWait;

Expand All @@ -65,13 +66,15 @@ public ProjectExplorer(
ActionsFactory actionsFactory,
NavigateToFile navigateToFile,
Menu menu,
CodenvyEditor editor) {
CodenvyEditor editor,
TestWebElementRenderChecker testWebElementRenderChecker) {
this.seleniumWebDriver = seleniumWebDriver;
this.loader = loader;
this.actionsFactory = actionsFactory;
this.navigateToFile = navigateToFile;
this.menu = menu;
this.editor = editor;
this.testWebElementRenderChecker = testWebElementRenderChecker;
loadPageTimeout = new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC);
redrawUiElementsWait = new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC);
PageFactory.initElements(seleniumWebDriver, this);
Expand Down Expand Up @@ -554,6 +557,9 @@ public void openContextMenuByPathSelectedItem(String path) {

/** wait for context menu. */
public void waitContextMenu() {
testWebElementRenderChecker.waitElementIsRendered(
"//tr[@id='gwt-debug-contextMenu/newGroup']/parent::tbody");

new WebDriverWait(seleniumWebDriver, WIDGET_TIMEOUT_SEC)
.until(ExpectedConditions.visibilityOfElementLocated(By.id(Locators.CONTEXT_MENU_ID)));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.selenium.pageobject;

import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.LOAD_PAGE_TIMEOUT_SEC;

import com.google.inject.Inject;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.che.selenium.core.SeleniumWebDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class TestWebElementRenderChecker {
private final SeleniumWebDriver seleniumWebDriver;
private final WebDriverWait loadPageWebDriverWait;

@Inject
public TestWebElementRenderChecker(SeleniumWebDriver seleniumWebDriver) {
this.seleniumWebDriver = seleniumWebDriver;
this.loadPageWebDriverWait = new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC);
}

/**
* wait until element have the same size between two checks it means that element is fully opened
*
* @param webElement list or context menu which need check
* @param seconds timeout for check
*/
public void waitElementIsRendered(WebElement webElement, int seconds) {
waitElementIsStatic(getFluentWait(seconds), webElement);
}

/**
* wait until element have the same size between two checks it means that element is fully opened
*
* @param webElement list or context menu which need check
*/
public void waitElementIsRendered(WebElement webElement) {
waitElementIsRendered(webElement, LOAD_PAGE_TIMEOUT_SEC);
}

/**
* wait until element have the same size between two checks it means that element is fully opened
*
* @param webElementXpath list or context menu Xpath which need check
*/
public void waitElementIsRendered(String webElementXpath) {
waitElementIsRendered(getAndWaitWebElement(webElementXpath));
}

/**
* wait until element have the same size between two checks it means that element is fully opened
*
* @param webElementXpath list or context menu Xpath which need check
* @param seconds timeout for check
*/
public void waitElementIsRendered(String webElementXpath, int seconds) {
waitElementIsRendered(getAndWaitWebElement(webElementXpath), seconds);
}

private Boolean dimensionsAreEquivalent(AtomicInteger sizeHashCode, Dimension newDimension) {
return sizeHashCode.get() == getSizeHashCode(newDimension);
}

private FluentWait<WebDriver> getFluentWait(int seconds) {
return new FluentWait<WebDriver>(seleniumWebDriver)
.withTimeout(seconds, TimeUnit.SECONDS)
.pollingEvery(200, TimeUnit.MILLISECONDS)
.ignoring(StaleElementReferenceException.class);
}

private void waitElementIsStatic(FluentWait<WebDriver> webDriverWait, WebElement webElement) {
AtomicInteger sizeHashCode = new AtomicInteger();

webDriverWait.until(
(ExpectedCondition<Boolean>)
driver -> {
Dimension newDimension = getAndWaitWebElement(webElement).getSize();

if (dimensionsAreEquivalent(sizeHashCode, newDimension)) {
return true;
} else {
sizeHashCode.set(getSizeHashCode(newDimension));
return false;
}
});
}

/**
* height is multiplied because we must avoid the situation when, in fact, different parties will
* give the same sum for example 15 + 25 == 25 + 15, but 15 + 25*10000 != 25 + 15*10000
*
* @param dimension consist partial sizes
* @return partial sizes sum with shift
*/
private int getSizeHashCode(Dimension dimension) {
return dimension.getWidth() + (dimension.getHeight() * 10000);
}

private WebElement getAndWaitWebElement(String webElementXpath) {
return loadPageWebDriverWait.until(
ExpectedConditions.visibilityOfElementLocated(By.xpath(webElementXpath)));
}

private WebElement getAndWaitWebElement(WebElement webElement) {
return loadPageWebDriverWait.until(ExpectedConditions.visibilityOf(webElement));
}
}