Skip to content

Commit a77d040

Browse files
authored
Fix various intermittent test issues (#2776)
- Disable pipeline triggers after failed tests - Avoid mousing over editable grid headers - Fix actionUrlTest.js to not use advanced JS method (`endsWith`) - Handle page load when signing in - Improve `WebDriverWrapper.mouseOut` - Improve `QueryGrid` synchronization
1 parent f029d70 commit a77d040

File tree

14 files changed

+108
-45
lines changed

14 files changed

+108
-45
lines changed

modules/simpletest/resources/scripts/validationTest/actionUrlTest.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ function doTest()
2121

2222
if (contextPath.length > 0) {
2323
var baseUrl = LABKEY.ActionURL.getBaseURL();
24-
if (!baseUrl.endsWith(contextPath + "/"))
24+
var suffix = contextPath + "/";
25+
var idx = baseUrl.indexOf(suffix);
26+
if (idx === -1 || idx !== baseUrl.length - suffix.length)
2527
errors[errors.length] = new Error("ActionURL.getBaseURL() = " + baseUrl);
2628
}
2729

src/org/labkey/test/LabKeySiteWrapper.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -405,11 +405,14 @@ public void attemptSignIn(String email, String password)
405405
setFormElement(Locator.id("email"), email);
406406
setFormElement(Locator.id("password"), password);
407407
WebElement signInButton = Locator.lkButton("Sign In").findElement(getDriver());
408-
signInButton.click();
409-
shortWait().until(ExpectedConditions.invisibilityOfElementLocated(Locator.byClass("signing-in-msg")));
410-
shortWait().until(ExpectedConditions.or(
411-
ExpectedConditions.stalenessOf(signInButton), // Successful login
412-
ExpectedConditions.presenceOfElementLocated(Locators.labkeyError.withText()))); // Error during sign-in
408+
doAndMaybeWaitForPageToLoad(10_000, () -> {
409+
signInButton.click();
410+
shortWait().until(ExpectedConditions.invisibilityOfElementLocated(Locator.byClass("signing-in-msg")));
411+
shortWait().until(ExpectedConditions.or(
412+
ExpectedConditions.stalenessOf(signInButton), // Successful login
413+
ExpectedConditions.presenceOfElementLocated(Locators.labkeyError.withText()))); // Error during sign-in
414+
return ExpectedConditions.stalenessOf(signInButton).apply(null);
415+
});
413416
}
414417

415418
public void signInShouldFail(String email, String password, String... expectedMessages)

src/org/labkey/test/Locators.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ private Locators() { }
3030
public static final Locator.XPathLocator folderTab = Locator.tagWithClass("div", "lk-nav-tabs-ct").append(Locator.tagWithClass("ul", "lk-nav-tabs")).childTag("li");
3131
public static final Locator.XPathLocator panelWebpartTitle = Locator.byClass("labkey-wp-title-text");
3232
public static final Locator.XPathLocator folderTitle = Locator.tagWithClass("a", "lk-body-title-folder");
33+
public static final Locator.XPathLocator loadingSpinner = Locator.byClass("fa-spinner");
3334

3435
public static Locator.XPathLocator headerContainer()
3536
{

src/org/labkey/test/TestScrubber.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.labkey.remoteapi.Connection;
2121
import org.labkey.remoteapi.SimplePostCommand;
2222
import org.labkey.test.components.html.Checkbox;
23+
import org.labkey.test.components.pipeline.PipelineTriggerWizard;
2324
import org.labkey.test.pages.core.admin.AllowedFileExtensionAdminPage;
2425
import org.labkey.test.pages.core.admin.BaseSettingsPage;
2526
import org.labkey.test.pages.core.admin.ConfigureFileSystemAccessPage;
@@ -160,6 +161,16 @@ public void cleanSiteSettings()
160161
TestLogger.error("Failed to reset site look and feel properties after test.", e);
161162
}
162163

164+
try
165+
{
166+
// Disable all pipeline triggers so that they don't show up as memory leaks in subsequent tests.
167+
PipelineTriggerWizard.disableAllPipelineTriggers(createDefaultConnection());
168+
}
169+
catch (Exception e)
170+
{
171+
TestLogger.error("Failed to disable pipeline triggers after test", e);
172+
}
173+
163174
}
164175

165176
@LogMethod(quiet = true)

src/org/labkey/test/WebDriverWrapper.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3000,14 +3000,17 @@ public void selectFolderTreeItem(String folderName)
30003000

30013001
/**
30023002
* Move mouse to the upper left corner of the document to dismiss tooltips and the like
3003-
* Will scroll page if necessary
30043003
*/
30053004
public void mouseOut()
30063005
{
30073006
try
30083007
{
3009-
scrollToTop();
3010-
new Actions(getDriver()).moveToLocation(0, 0).perform();
3008+
new Actions(getDriver())
3009+
.moveToLocation(0, 0)
3010+
// Add a little wiggle to make sure tooltips notice
3011+
.moveByOffset(4, 4)
3012+
.moveByOffset(-2, -2)
3013+
.perform();
30113014
}
30123015
catch (WebDriverException ignore) { }
30133016
}

src/org/labkey/test/components/domain/DomainDesigner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public class ElementCache extends BaseDomainDesigner<?>.ElementCache
4848
protected final DomainPanel<?, ?> propertiesPanel = new DomainPanel.DomainPanelFinder(getDriver()).index(0)
4949
.timeout(WAIT_FOR_JAVASCRIPT).findWhenNeeded(this);
5050
protected final DomainFormPanel fieldsPanel = new DomainFormPanel.DomainFormPanelFinder(getDriver())
51-
.index(getFieldPanelIndex()).timeout(1000).findWhenNeeded();
51+
.index(getFieldPanelIndex()).timeout(2_000).findWhenNeeded();
5252

5353
protected int getFieldPanelIndex()
5454
{

src/org/labkey/test/components/pipeline/PipelineTriggerWizard.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
package org.labkey.test.components.pipeline;
1717

1818
import org.jetbrains.annotations.NotNull;
19+
import org.labkey.remoteapi.CommandException;
20+
import org.labkey.remoteapi.Connection;
21+
import org.labkey.remoteapi.query.ContainerFilter;
22+
import org.labkey.remoteapi.query.Filter;
1923
import org.labkey.test.Locator;
2024
import org.labkey.test.WebDriverWrapper;
2125
import org.labkey.test.WebTestHelper;
@@ -24,11 +28,14 @@
2428
import org.labkey.test.components.html.Checkbox;
2529
import org.labkey.test.components.html.Input;
2630
import org.labkey.test.components.html.OptionSelect;
31+
import org.labkey.test.util.query.QueryApiHelper;
2732
import org.openqa.selenium.Alert;
2833
import org.openqa.selenium.WebDriver;
2934
import org.openqa.selenium.WebElement;
3035
import org.openqa.selenium.support.ui.ExpectedConditions;
3136

37+
import java.io.IOException;
38+
import java.util.List;
3239
import java.util.Map;
3340

3441
import static org.junit.Assert.assertTrue;
@@ -61,6 +68,18 @@ public static PipelineTriggerWizard beginAt(WebDriverWrapper driver, String cont
6168
return new PipelineTriggerWizard(driver.getDriver());
6269
}
6370

71+
public static void disableAllPipelineTriggers(Connection connection) throws IOException, CommandException
72+
{
73+
QueryApiHelper queryApiHelper = new QueryApiHelper(connection, "/", "pipeline", "TriggerConfigurations");
74+
List<Map<String, Object>> triggers = queryApiHelper.selectRows(List.of("rowId", "enabled"),
75+
List.of(new Filter("enabled", true)), List.of(), ContainerFilter.AllFolders).getRows();
76+
if (!triggers.isEmpty())
77+
{
78+
triggers.forEach(trigger -> trigger.put("enabled", false));
79+
queryApiHelper.updateRows(triggers);
80+
}
81+
}
82+
6483
@Override
6584
public WebElement getComponentElement()
6685
{

src/org/labkey/test/components/ui/grids/EditableGrid.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,8 @@ public String getErrorPopoverText(int row, CharSequence columnIdentifier)
11601160
*/
11611161
public String getCellPopoverText(int row, CharSequence columnIdentifier)
11621162
{
1163+
dismissPopover(); // Other popovers can block the target cell
1164+
getWrapper().mouseOver(Locator.tag("td").findElement(getRow(row))); // Avoid passing over any header cells on the way to the target cell
11631165
WebElement cellDiv = Locator.tagWithClass("div", "cellular-display").findElement(getCell(row, columnIdentifier));
11641166
getWrapper().mouseOver(cellDiv); // cause the tooltip to be present
11651167
return Optional.ofNullable(WebDriverWrapper.waitFor(()-> Locators.popover.findElementOrNull(getDriver()), 1000))
@@ -1170,7 +1172,9 @@ public String getCellPopoverText(int row, CharSequence columnIdentifier)
11701172
public void dismissPopover()
11711173
{
11721174
Locators.popover.findOptionalElement(getDriver()).ifPresent(popover -> {
1175+
getWrapper().mouseOver(popover);
11731176
getWrapper().mouseOut();
1177+
getWrapper().mouseOver(elementCache().getGridHeaderManager().getColumnHeader(0).getElement());
11741178
getWrapper().shortWait().until(ExpectedConditions.invisibilityOf(popover));
11751179
});
11761180
}

src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ public FieldSelectionDialog removeAllSelectedFields()
400400
continue;
401401
}
402402

403+
getWrapper().mouseOver(removeIcon);
403404
removeIcon.click();
404405
}
405406

src/org/labkey/test/components/ui/grids/QueryGrid.java

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -221,18 +221,18 @@ public QueryGrid waitForRecordCount(int expectedCount, int milliseconds)
221221
@Override
222222
public void doAndWaitForUpdate(Runnable func)
223223
{
224-
waitForLoaded();
225-
Optional<WebElement> optionalStatus = elementCache().selectionStatusContainerLoc.findOptionalElement(elementCache());
224+
super.doAndWaitForUpdate(() ->
225+
{
226+
WebElement status = hasSelectColumn() ? Locators.selectionStatusContainerLoc.waitForElement(this, 5_000) : null;
226227

227-
func.run();
228+
func.run();
228229

229-
optionalStatus.ifPresent(el -> {
230-
getWrapper().shortWait().until(ExpectedConditions.stalenessOf(el));
231-
elementCache().selectionStatusContainerLoc.waitForElement(this, 5_000);
230+
if (status != null)
231+
{
232+
getWrapper().shortWait().until(ExpectedConditions.stalenessOf(status));
233+
Locators.selectionStatusContainerLoc.waitForElement(this, 5_000);
234+
}
232235
});
233-
234-
waitForLoaded();
235-
clearElementCache();
236236
}
237237

238238

@@ -789,19 +789,24 @@ protected ElementCache elementCache()
789789
return (ElementCache) super.elementCache();
790790
}
791791

792+
protected static class Locators
793+
{
794+
static final Locator.XPathLocator selectionStatusContainerLoc = Locator.byClass("selection-status");
795+
}
796+
792797
protected class ElementCache extends ResponsiveGrid<QueryGrid>.ElementCache
793798
{
799+
794800
final GridBar gridBar = new GridBar.GridBarFinder().findWhenNeeded(QueryGrid.this);
795801

796-
WebElement saveViewButton = Locator.button("Save").findWhenNeeded(getDriver());
802+
final WebElement saveViewButton = Locator.button("Save").findWhenNeeded(getDriver());
797803

798804
final BootstrapMenu viewMenu = new MultiMenu.MultiMenuFinder(getDriver()).withText("Views").findWhenNeeded(this);
799805

800-
final Locator.XPathLocator selectionStatusContainerLoc = Locator.tagWithClass("div", "selection-status");
801-
final Locator selectAllBtnLoc = selectionStatusContainerLoc.append(Locator.tagWithClass("span", "selection-status__select-all")
802-
.child(Locator.buttonContainingText("Select")));
803-
final Locator clearBtnLoc = selectionStatusContainerLoc.append(Locator.byClass("selection-status__clear-all")
804-
.child(Locator.tag("button")));
806+
final Locator selectAllBtnLoc = Locators.selectionStatusContainerLoc.append(Locator.byClass("selection-status__select-all")
807+
.childTag("button"));
808+
final Locator clearBtnLoc = Locators.selectionStatusContainerLoc.append(Locator.byClass("selection-status__clear-all")
809+
.childTag("button"));
805810

806811
final WebElement filterStatusPanel = Locator.css("div.grid-panel__filter-status").findWhenNeeded(this);
807812

0 commit comments

Comments
 (0)