Skip to content

Commit

Permalink
Hardening against intermittent failures
Browse files Browse the repository at this point in the history
  • Loading branch information
OndrejKotek committed Mar 8, 2024
1 parent 7dcacb4 commit 94e2378
Show file tree
Hide file tree
Showing 16 changed files with 88 additions and 38 deletions.
18 changes: 13 additions & 5 deletions common/src/main/java/org/jboss/hal/testsuite/Console.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.jboss.hal.testsuite.util.Library;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

Expand Down Expand Up @@ -127,11 +128,18 @@ public void verify(PlaceRequest placeRequest) {
/** Waits until all notifications are gone. */
public void waitNoNotification() {
List<WebElement> dismissibleNotifications = By.cssSelector(DOT + alertDismissable).findElements(browser);
for (WebElement notification : dismissibleNotifications) {
WebElement button = notification.findElement(By.cssSelector("button.close"));
if (button != null) {
button.click();
for (int remainingExpected = dismissibleNotifications.size(); !dismissibleNotifications.isEmpty()
&& remainingExpected > 0; remainingExpected--) {

try {
WebElement button = dismissibleNotifications.get(0).findElement(By.cssSelector("button.close"));
if (button != null) {
button.click();
}
} catch (StaleElementReferenceException ex) {
// Ignore the exception, the notification may be gone before clicking
}
dismissibleNotifications = By.cssSelector(DOT + alertDismissable).findElements(browser);
}
waitModel().until().element(By.cssSelector(DOT + toastNotificationsListPf + ":empty")).is().present();
}
Expand All @@ -152,7 +160,7 @@ public boolean verifyNoError() {
}

private void verifyNotification(String css) {
waitModel().until() // use waitModel() since it might take some time until the notification is visible
waitModel().until() // use waitModel() since the notification might take some time until the notification is visible
.element(By.cssSelector(DOT + toastNotificationsListPf + " ." + css))
.is().visible();
}
Expand Down
11 changes: 10 additions & 1 deletion common/src/main/java/org/jboss/hal/testsuite/CrudOperations.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@
import org.jboss.hal.testsuite.creaper.ManagementClientProvider;
import org.jboss.hal.testsuite.creaper.ResourceVerifier;
import org.jboss.hal.testsuite.fragment.AddResourceDialogFragment;
import org.jboss.hal.testsuite.fragment.EmptyState;
import org.jboss.hal.testsuite.fragment.FormFragment;
import org.jboss.hal.testsuite.fragment.TableFragment;
import org.openqa.selenium.TimeoutException;
import org.wildfly.extras.creaper.core.online.OnlineManagementClient;
import org.wildfly.extras.creaper.core.online.operations.Address;

import static org.jboss.arquillian.graphene.Graphene.waitGui;
import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME;

/** Methods useful to test and verify CRUD operations in application views. */
Expand Down Expand Up @@ -76,7 +79,13 @@ public void createSingleton(Address address, FormFragment form, Consumer<FormFra
/** Adds a singleton resource using the main action of an empty state and the specified initial form values. */
public void createSingleton(Address address, FormFragment form, Consumer<FormFragment> initialValues,
VerifyChanges verifyChanges) throws Exception {
form.emptyState().mainAction();
try {
EmptyState emptyState = form.emptyState();
waitGui().until().element(emptyState.getRoot()).is().visible();
emptyState.mainAction();
} catch (TimeoutException ex) {
form.emptyState().mainAction();
}
if (initialValues != null) {
AddResourceDialogFragment dialog = console.addResourceDialog();
initialValues.accept(dialog.getForm()); // use the form of add resource dialog!
Expand Down
4 changes: 2 additions & 2 deletions common/src/main/java/org/jboss/hal/testsuite/Random.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ public static String jndiName(String name) {
return JNDI_PREFIX + name;
}

/** Returns a random integer between 0 and 99 */
/** Returns a random integer between 1 and 99 */
public static int number() {
return RandomUtils.nextInt(0, 100);
return RandomUtils.nextInt(1, 100);
}

/** Returns a random double between 0.001 and 99.999 */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
package org.jboss.hal.testsuite.fragment;

import org.jboss.arquillian.graphene.fragment.Root;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

import static org.jboss.arquillian.graphene.Graphene.waitModel;
import static org.jboss.hal.resources.CSS.blankSlatePfMainAction;
import static org.jboss.hal.resources.CSS.btnPrimary;

Expand All @@ -30,6 +32,7 @@ public class EmptyState {

/** Clicks on the main action */
public void mainAction() {
waitModel().until().element(root, By.cssSelector("." + blankSlatePfMainAction + " button." + btnPrimary)).is().visible();
primaryButton.click();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@
import org.openqa.selenium.By;
import org.openqa.selenium.ElementClickInterceptedException;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.ExpectedConditions;

import static org.jboss.arquillian.graphene.Graphene.createPageFragment;
import static org.jboss.arquillian.graphene.Graphene.waitGui;
Expand Down Expand Up @@ -168,6 +170,11 @@ public void text(String name, String value) {
waitGui().until().element(inputElement).value().equalTo("");
inputElement.sendKeys(value);
waitGui().until().element(inputElement).value().equalTo(value);

// get rid of any open auto suggestions popup, which might interfere with save or cancel buttons
inputElement.sendKeys(Keys.TAB);
waitGui().until(ExpectedConditions.invisibilityOfAllElements(ByJQuery
.selector(DOT + autocompleteSuggestions).findElements(browser)));
}

public void textByLabel(String labelContent, String value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.openqa.selenium.support.FindBy;

import static org.jboss.arquillian.graphene.Graphene.waitGui;
import static org.jboss.arquillian.graphene.Graphene.waitModel;
import static org.jboss.hal.resources.CSS.columnAction;
import static org.jboss.hal.resources.CSS.halTableButtons;
import static org.jboss.hal.testsuite.Selectors.contains;
Expand Down Expand Up @@ -91,6 +92,7 @@ public WebElement button(String text) {
*/
public void select(String value) {
By selector = ByJQuery.selector("td" + contains(value));
waitModel().until().element(root, selector).is().present();
goToPageWithElement(selector);
WebElement rowElement = root.findElement(selector);

Expand Down Expand Up @@ -120,6 +122,7 @@ public void select(String value) {
/** Clicks on the &lt;action&gt; column in the row which contains "&lt;value&gt;". */
public void action(String value, String action) {
By selector = ByJQuery.selector("td" + contains(value) + " ~ td button." + columnAction + contains(action));
waitModel().until().element(root, selector).is().present();
goToPageWithElement(selector);
root.findElement(selector).click();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ public void selectPrimary(String id) {
public void selectSecondary(String primaryId, String secondaryId) {
WebElement primaryMenuItem = root.findElement(By.cssSelector("#" + primaryId + " > a"));
new Actions(browser).moveToElement(primaryMenuItem).perform();
primaryMenuItem.click();
waitGui().until().element(By.id(primaryId + "-secondary")).is().visible();
selectItem(secondaryId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,9 @@ public void navigate(Map<String, String> params) {
public void navigateAgain(String name, String value) {
browser.navigate().refresh();
navigate(name, value);
if (!console.verifyNoError()) {
browser.navigate().refresh();
navigate(name, value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
import static org.jboss.hal.testsuite.fixtures.ElytronFixtures.SQL_UPDATE2;
import static org.jboss.hal.testsuite.fixtures.ElytronFixtures.datasourceAddress;
import static org.jboss.hal.testsuite.fixtures.ElytronFixtures.jdbcRealmAddress;

@RunWith(Arquillian.class)
public class JDBCRealmTest {

Expand Down Expand Up @@ -628,9 +629,10 @@ public void principalQueryModularCryptMapperUpdate() throws Exception {
TableFragment table = page.getPrincipalQueryTable();
FormFragment form = page.getPrincipalQueryMcryptForm();
table.bind(form);
jdbcTable.filter(JDBC_RLM_UPDATE);
jdbcTable.action(JDBC_RLM_UPDATE, PQ_LABEL);
waitGui().until().element(table.getRoot()).is().visible();
table.select(SQL_MCM_UPD);
table.filterAndSelect(SQL_MCM_UPD);
page.getPrincipalQueryTabs().select(MCRYPT_MAPPER_TAB);
long number = 23;
ModelNode mapper = new ModelNode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,10 @@ public void verifyAttributes() throws IOException {
@Test
public void verifyCreationTime() throws IOException {
navigateToDeploymentRuntime();
long creationTimeInMillis = System.currentTimeMillis();
long creationTimeInMillisBefore = System.currentTimeMillis();
deploymentBrowser.get(DEPLOYMENT_URL);
long creationTimeInMillisAfter = System.currentTimeMillis();
long creationTimeInMillis = ((creationTimeInMillisAfter - creationTimeInMillisBefore) / 2) + creationTimeInMillisBefore;
reloadSessions();
String sessionId = getSessionsFromModel().get(0);
page.getSessionsTable().select(sessionId);
Expand All @@ -223,15 +225,16 @@ public void verifyLastAccessedTime() throws IOException, InterruptedException {
reloadSessions();
String sessionId = getSessionsFromModel().get(0);
page.getSessionsTable().select(sessionId);
long start = System.currentTimeMillis();
long end = start + TimeUnit.MINUTES.toMillis(1);
TimeUnit.MINUTES.sleep(1);
TimeUnit.SECONDS.sleep(5);
long accessTimeBefore = System.currentTimeMillis();
deploymentBrowser.findElement(By.cssSelector("input[value=\"Increment\"")).click();
long accessTimeAfter = System.currentTimeMillis();
long accessTime = ((accessTimeAfter - accessTimeBefore) / 2) + accessTimeBefore;
reloadSessions();
List<WebElement> selectedRowColumns = page.getSessionsTable().getRoot().findElements(By.cssSelector("tr.selected > td"));
String lastAccessedTime = selectedRowColumns.get(2).getText();
Calendar lastAccessedTimeCalendar = Calendar.getInstance();
lastAccessedTimeCalendar.setTimeInMillis(end);
lastAccessedTimeCalendar.setTimeInMillis(accessTime);
Assert.assertEquals("Last accessed time should be matching", DATE_FORMAT.format(lastAccessedTimeCalendar.getTime()), lastAccessedTime);
invalidateSession(sessionId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ public class SingleSignOnAddTest {
@BeforeClass
public static void setUp() throws IOException {
operations.add(httpAuthenticationFactoryAddress(HTTP_AUTH_CREATE),
Values.of(HTTP_SERVER_MECH_FACTORY, "global").and(SECURITY_DOMAIN, "ApplicationDomain"));
Values.of(HTTP_SERVER_MECH_FACTORY, "global").and(SECURITY_DOMAIN, "ApplicationDomain")).assertSuccess();
operations.add(applicationSecurityDomain(APPLICATION_SECURITY_DOMAIN_TO_BE_TESTED2),
Values.of(ApplicationSecurityDomainFixtures.HTTP_AUTHENTICATION_FACTORY, HTTP_AUTH_CREATE));
Values.of(ApplicationSecurityDomainFixtures.HTTP_AUTHENTICATION_FACTORY, HTTP_AUTH_CREATE)).assertSuccess();
operations.add(ElytronFixtures.keyStoreAddress(KEY_STORE_TO_BE_ADDED),
Values.of(TYPE, ElytronFixtures.JKS)
.and(ElytronFixtures.CREDENTIAL_REFERENCE, new ModelNodeGenerator.ModelNodePropertiesBuilder()
.addProperty(ElytronFixtures.CREDENTIAL_REFERENCE_CLEAR_TEXT, Random.name()).build()));
.addProperty(ElytronFixtures.CREDENTIAL_REFERENCE_CLEAR_TEXT, Random.name()).build())).assertSuccess();
}

@AfterClass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ public class AJPListenerConfigurationTest {

@BeforeClass
public static void setUp() throws IOException, CommandFailedException {
operations.add(IOFixtures.bufferPoolAddress(BUFFER_POOL_TO_BE_EDITED));
operations.add(IOFixtures.workerAddress(WORKER_TO_BE_EDITED));
operations.add(serverAddress(UNDERTOW_SERVER_TO_BE_TESTED));
operations.add(IOFixtures.bufferPoolAddress(BUFFER_POOL_TO_BE_EDITED)).assertSuccess();
operations.add(IOFixtures.workerAddress(WORKER_TO_BE_EDITED)).assertSuccess();
operations.add(serverAddress(UNDERTOW_SERVER_TO_BE_TESTED)).assertSuccess();
client.apply(new AddLocalSocketBinding(SOCKET_BINDING));
client.apply(new AddLocalSocketBinding(SOCKET_BINDING_TO_BE_EDITED));
client.apply(new AddLocalSocketBinding(SOCKET_REDIRECT_TO_BE_EDITED));
operations.add(serverAddress(UNDERTOW_SERVER_TO_BE_TESTED).and("ajp-listener", AJP_LISTENER_TO_BE_EDITED),
Values.of("socket-binding", SOCKET_BINDING.toLowerCase() + "ref"));
Values.of("socket-binding", SOCKET_BINDING.toLowerCase() + "ref")).assertSuccess();
}

@AfterClass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ private static Address crawlerAddress(String servletContainer) {

@BeforeClass
public static void setUp() throws IOException {
operations.add(UndertowFixtures.servletContainerAddress(SERVLET_CONTAINER_EDIT));
operations.add(SERVLET_CONTAINER_EDIT_CRAWLER_ADDRESS);
operations.add(UndertowFixtures.servletContainerAddress(SERVLET_CONTAINER_CRAWLER_CREATE));
operations.add(UndertowFixtures.servletContainerAddress(SERVLET_CONTAINER_CRAWLER_REMOVE));
operations.add(crawlerAddress(SERVLET_CONTAINER_CRAWLER_REMOVE));
operations.add(UndertowFixtures.servletContainerAddress(SERVLET_CONTAINER_EDIT)).assertSuccess();
operations.add(SERVLET_CONTAINER_EDIT_CRAWLER_ADDRESS).assertSuccess();
operations.add(UndertowFixtures.servletContainerAddress(SERVLET_CONTAINER_CRAWLER_CREATE)).assertSuccess();
operations.add(UndertowFixtures.servletContainerAddress(SERVLET_CONTAINER_CRAWLER_REMOVE)).assertSuccess();
operations.add(crawlerAddress(SERVLET_CONTAINER_CRAWLER_REMOVE)).assertSuccess();
}

@AfterClass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ private static Address webSocketsAddress(String servletContainer) {

@BeforeClass
public static void setUp() throws IOException {
operations.add(UndertowFixtures.servletContainerAddress(SERVLET_CONTAINER_EDIT));
operations.add(SERVLET_CONTAINER_EDIT_WEB_SOCKETS_ADDRESS);
operations.add(UndertowFixtures.servletContainerAddress(SERVLET_CONTAINER_WEB_SOCKETS_CREATE));
operations.add(UndertowFixtures.servletContainerAddress(SERVLET_CONTAINER_WEB_SOCKETS_REMOVE));
operations.add(webSocketsAddress(SERVLET_CONTAINER_WEB_SOCKETS_REMOVE));
operations.add(IOFixtures.bufferPoolAddress(BUFFER_POOL_TO_BE_EDITED));
operations.add(IOFixtures.workerAddress(WORKER_TO_BE_EDITED));
operations.add(UndertowFixtures.servletContainerAddress(SERVLET_CONTAINER_EDIT)).assertSuccess();
operations.add(SERVLET_CONTAINER_EDIT_WEB_SOCKETS_ADDRESS).assertSuccess();
operations.add(UndertowFixtures.servletContainerAddress(SERVLET_CONTAINER_WEB_SOCKETS_CREATE)).assertSuccess();
operations.add(UndertowFixtures.servletContainerAddress(SERVLET_CONTAINER_WEB_SOCKETS_REMOVE)).assertSuccess();
operations.add(webSocketsAddress(SERVLET_CONTAINER_WEB_SOCKETS_REMOVE)).assertSuccess();
operations.add(IOFixtures.bufferPoolAddress(BUFFER_POOL_TO_BE_EDITED)).assertSuccess();
operations.add(IOFixtures.workerAddress(WORKER_TO_BE_EDITED)).assertSuccess();
}

@AfterClass
Expand Down Expand Up @@ -117,7 +117,7 @@ public void editBufferPool() throws Exception {
public void editDeflaterLevel() throws Exception {
navigateToWebSocketsForm(SERVLET_CONTAINER_EDIT);
crudOperations.update(SERVLET_CONTAINER_EDIT_WEB_SOCKETS_ADDRESS, page.getWebSocketsForm(), "deflater-level",
Random.number(0, 10));
Random.number(0, 9));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.openqa.selenium.By;
import org.wildfly.extras.creaper.core.online.ModelNodeResult;
import org.wildfly.extras.creaper.core.online.OnlineManagementClient;
import org.wildfly.extras.creaper.core.online.operations.Address;
import org.wildfly.extras.creaper.core.online.operations.Operations;
import org.wildfly.extras.creaper.core.online.operations.Values;

import static java.util.stream.Collectors.toList;
import static org.jboss.arquillian.graphene.Graphene.waitGui;
import static org.jboss.hal.dmr.ModelDescriptionConstants.*;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse;
Expand Down Expand Up @@ -70,6 +72,7 @@ public void setUp() throws Exception {
FinderFragment finder = console.finder(NameTokens.RUNTIME);
finder.column(Ids.STANDALONE_SERVER_COLUMN)
.selectItem(Ids.hostServer(Ids.STANDALONE_HOST, serverEnvironmentUtils.getServerHostName()));
waitGui().until().element(By.id("open-ports")).is().present();
preview = finder.preview(ServerPreviewFragment.class);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,24 @@ public void setUp() throws Exception {

@Test
public void memory() {
assertUsage(preview.getHeapUsed(), "heap used", heapUsed, 20);
assertHeapUsed(preview.getHeapUsed(), "heap used", heapUsed, 60);
assertUsage(preview.getHeapCommitted(), "heap committed", heapCommitted, 10);
assertUsage(preview.getNonHeapUsed(), "non-heap used", nonHeapUsed, 10);
assertUsage(preview.getNonHeapCommitted(), "non-heap committed", nonHeapCommitted, 10);
assertUsage(preview.getThreads(), "threads", daemons, 5);
assertUsage(preview.getThreads(), "threads", daemons, 30);
}

private void assertUsage(WebElement element, String message, long expected, long delta) {
long actual = Long.parseLong(element.getAttribute("aria-valuenow"));
assertTrue(message, Math.abs(expected - actual) <= delta);
String detailedMessage = String.format("'" + message + "' not match (expected: %d, actual: %d, max. delta: %d)",
expected, actual, delta);
assertTrue(detailedMessage, Math.abs(expected - actual) <= delta);
}

private void assertHeapUsed(WebElement element, String message, long expected, long delta) {
long actual = Long.parseLong(element.getAttribute("aria-valuenow"));
String detailedMessage = String.format("'" + message + "' not match (expected: %d, actual: %d, max. delta: %d)",
expected, actual, delta);
assertTrue(detailedMessage, Math.abs(expected - actual) <= delta || expected > actual);
}
}

0 comments on commit 94e2378

Please sign in to comment.