Skip to content

Commit 9960239

Browse files
authored
Merge pull request #619 from jtnord/click_and_menu_flakes
deflake `Control.click` and `Control.selectDropdownMenu`
2 parents 2f748dc + 13a110f commit 9960239

1 file changed

Lines changed: 28 additions & 12 deletions

File tree

src/main/java/org/jenkinsci/test/acceptance/po/Control.java

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package org.jenkinsci.test.acceptance.po;
22

33
import java.time.Duration;
4+
import java.util.concurrent.TimeUnit;
5+
46
import javax.annotation.Nullable;
57

68
import org.apache.commons.lang3.StringUtils;
79
import org.jenkinsci.test.acceptance.selenium.Scroller;
810
import org.openqa.selenium.By;
11+
import org.openqa.selenium.ElementClickInterceptedException;
912
import org.openqa.selenium.JavascriptExecutor;
10-
import org.openqa.selenium.Keys;
1113
import org.openqa.selenium.NoSuchElementException;
1214
import org.openqa.selenium.WebElement;
1315
import org.openqa.selenium.support.ui.Select;
@@ -103,7 +105,14 @@ public void check(boolean state) {
103105
* @see #clickAndWaitToBecomeStale(Duration)
104106
*/
105107
public void click() {
106-
resolve().click();
108+
WebElement we = resolve();
109+
// button may be obscured by say the "Save Apply" screen so we wait as Selenium will do a scroll but the CSS
110+
// can take a while to update the layout \o/
111+
waitFor(we).
112+
withTimeout(1, TimeUnit.SECONDS).
113+
pollingEvery(100, TimeUnit.MILLISECONDS).
114+
ignoring(ElementClickInterceptedException.class).
115+
until(() -> {we.click(); return true;});
107116
}
108117

109118

@@ -184,17 +193,24 @@ public void set(Object text) {
184193
* @param type
185194
* Class with {@link Describable} annotation.
186195
*/
187-
public void selectDropdownMenu(Class type) {
196+
public void selectDropdownMenu(Class<?> type) {
188197
click();
189-
findCaption(type,findDropDownMenuItem).click();
190-
elasticSleep(1000);
198+
WebElement we = findCaption(type,findDropDownMenuItem);
199+
// the element may not yet be visible so wait for it to become shown after the click above
200+
waitFor(we).pollingEvery(100L, TimeUnit.MILLISECONDS).withTimeout(1, TimeUnit.SECONDS).until(() -> we.isDisplayed());
201+
we.click();
202+
// wait until the menu is hidden
203+
waitFor(we).pollingEvery(100L, TimeUnit.MILLISECONDS).withTimeout(1, TimeUnit.SECONDS).until(() -> !we.isDisplayed());
191204
}
192205

193206
public void selectDropdownMenu(String displayName) {
194207
click();
195-
elasticSleep(1000);
196-
findDropDownMenuItem.find(displayName).click();
197-
elasticSleep(1000);
208+
WebElement we = findDropDownMenuItem.find(displayName);
209+
// the element may not yet be visible so wait for it to become shown after the click above
210+
waitFor(we).pollingEvery(100L, TimeUnit.MILLISECONDS).withTimeout(1, TimeUnit.SECONDS).until(() -> we.isDisplayed());
211+
we.click();
212+
// wait until the menu is hidden
213+
waitFor(we).pollingEvery(100L, TimeUnit.MILLISECONDS).withTimeout(1, TimeUnit.SECONDS).until(() -> !we.isDisplayed());
198214
}
199215

200216
/**
@@ -218,9 +234,9 @@ protected WebElement find(String caption) {
218234
" }" +
219235
");"
220236
);
221-
222-
WebElement context = findElement(menuButton, by.xpath("ancestor::*[contains(@class,'yui-menu-button')]/.."));
223-
WebElement e = findElement(context, by.link(caption));
237+
// we can not use `Select` as these are YUI menus and we need to wait for it to be visible
238+
WebElement menu = findElement(menuButton, by.xpath("ancestor::*[contains(@class,'yui-menu-button')]/.."));
239+
WebElement e = findElement(menu, by.link(caption));
224240
return e;
225241
}
226242
};
@@ -229,7 +245,7 @@ protected WebElement find(String caption) {
229245
* For alternative use when the 'yui-menu-button' doesn't exist.
230246
* @param type
231247
*/
232-
public void selectDropdownMenuAlt(Class type) {
248+
public void selectDropdownMenuAlt(Class<?> type) {
233249
findCaption(type,findDropDownMenuItemBySelector);
234250
elasticSleep(1000);
235251
}

0 commit comments

Comments
 (0)