Skip to content

Commit a1d682f

Browse files
authored
Fix some intermittent test failures (#2495)
1 parent b63590f commit a1d682f

3 files changed

Lines changed: 60 additions & 53 deletions

File tree

src/org/labkey/test/WebDriverWrapper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ public <T> T executeScript(@Language("JavaScript") String script, Class<T> expec
532532
* Wrapper for synchronous execution of asynchronous JavaScript. This wrapper extracts the 'callback' from the argument list
533533
* See {@link JavascriptExecutor#executeAsyncScript(java.lang.String, java.lang.Object...)} for details
534534
*/
535-
public Object executeAsyncScript(@Language("XPath") String script, Object... arguments)
535+
public Object executeAsyncScript(@Language("JavaScript") String script, Object... arguments)
536536
{
537537
script = "var callback = arguments[arguments.length - 1];\n" + // See WebDriver documentation for details on injected callback
538538
"try {" +
@@ -541,7 +541,7 @@ public Object executeAsyncScript(@Language("XPath") String script, Object... arg
541541
return ((JavascriptExecutor) getDriver()).executeAsyncScript(script, arguments);
542542
}
543543

544-
public <T> T executeAsyncScript(String script, Class<T> expectedResultType, Object... arguments)
544+
public <T> T executeAsyncScript(@Language("JavaScript") String script, Class<T> expectedResultType, Object... arguments)
545545
{
546546
Object o = executeAsyncScript(script, arguments);
547547
if (o != null && !expectedResultType.isAssignableFrom(o.getClass()))

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.stream.Collectors;
2828

2929
import static org.labkey.test.WebDriverWrapper.WAIT_FOR_JAVASCRIPT;
30+
import static org.labkey.test.WebDriverWrapper.waitFor;
3031

3132
/**
3233
* Automates the LabKey ui component defined in: packages/components/src/components/domainproperties/DomainForm.tsx
@@ -43,6 +44,12 @@ private DomainFormPanel(WebElement element, WebDriver driver)
4344
super(element, driver);
4445
}
4546

47+
@Override
48+
protected void waitForReady()
49+
{
50+
waitFor(() -> !BootstrapLocators.loadingSpinner.existsIn(this), "Loading spinner still present", 2_000);
51+
}
52+
4653
public static List<AdvancedFieldSetting> advancedSettingsFromFieldDefinition(FieldDefinition def)
4754
{
4855
List<AdvancedFieldSetting> advancedSettings = new ArrayList<>();

src/org/labkey/test/tests/SimpleModuleTest.java

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@
1515
*/
1616
package org.labkey.test.tests;
1717

18+
import org.apache.commons.lang3.StringUtils;
1819
import org.apache.commons.text.similarity.LevenshteinDistance;
1920
import org.apache.hc.core5.http.HttpStatus;
21+
import org.intellij.lang.annotations.Language;
2022
import org.jetbrains.annotations.Nullable;
23+
import org.junit.Assert;
2124
import org.junit.BeforeClass;
2225
import org.junit.Test;
2326
import org.junit.experimental.categories.Category;
@@ -58,6 +61,7 @@
5861
import org.labkey.test.util.Maps;
5962
import org.labkey.test.util.PortalHelper;
6063
import org.labkey.test.util.RReportHelper;
64+
import org.labkey.test.util.TestLogger;
6165
import org.labkey.test.util.WikiHelper;
6266
import org.labkey.test.util.ext4cmp.Ext4FieldRef;
6367
import org.openqa.selenium.By;
@@ -76,6 +80,8 @@
7680
import java.util.List;
7781
import java.util.Map;
7882
import java.util.StringJoiner;
83+
import java.util.regex.Matcher;
84+
import java.util.regex.Pattern;
7985

8086
import static org.junit.Assert.assertEquals;
8187
import static org.junit.Assert.assertFalse;
@@ -202,7 +208,7 @@ protected String getProjectName()
202208
@LogMethod
203209
public static void initTest()
204210
{
205-
SimpleModuleTest init = (SimpleModuleTest) getCurrentTest();
211+
SimpleModuleTest init = getCurrentTest();
206212
init.doSetup();
207213
}
208214

@@ -228,8 +234,6 @@ protected void doSetup()
228234

229235
goToProjectHome();
230236
portalHelper.addWebPart("Data Views");
231-
for (int i = 0; i < 5; i ++)
232-
portalHelper.moveWebPart("Data Views", PortalHelper.Direction.UP);
233237

234238
ProjectSettingsPage projectSettingsPage = goToProjectSettings();
235239
projectSettingsPage.setDefaultDateTimeDisplayInherited(false);
@@ -436,7 +440,7 @@ private void doTestColumnValidators() throws Exception
436440
deleteCmd.execute(createDefaultConnection(), getProjectName());
437441
}
438442

439-
private void submitAndTestExpectedFailure(Command cmd, String expectedError) throws Exception
443+
private void submitAndTestExpectedFailure(Command<?, ?> cmd, String expectedError) throws Exception
440444
{
441445
try
442446
{
@@ -725,7 +729,7 @@ else if (name.equalsIgnoreCase("F150"))
725729
));
726730
try
727731
{
728-
SaveRowsResponse updateRows = updateCmd.execute(cn, getProjectName() + "/" + FOLDER_NAME);
732+
updateCmd.execute(cn, getProjectName() + "/" + FOLDER_NAME);
729733
fail("Expected to throw CommandException");
730734
}
731735
catch (CommandException ex)
@@ -737,7 +741,7 @@ else if (name.equalsIgnoreCase("F150"))
737741
// Make sure that the schema isn't resolved if the module is not enabled in the container
738742
try
739743
{
740-
SaveRowsResponse updateRows = updateCmd.execute(cn, "Shared");
744+
updateCmd.execute(cn, "Shared");
741745
fail("Expected to throw CommandException");
742746
}
743747
catch (CommandException ex)
@@ -809,7 +813,7 @@ else if (name.equalsIgnoreCase("F150"))
809813
try
810814
{
811815
log("** Trying to delete Vehicles from a different container");
812-
SaveRowsResponse deleteResp = deleteCmd.execute(cn, getProjectName() + "/" + FOLDER_NAME);
816+
deleteCmd.execute(cn, getProjectName() + "/" + FOLDER_NAME);
813817
fail("Expected to throw CommandException");
814818
}
815819
catch (CommandException ex)
@@ -845,7 +849,7 @@ private void validateThumbnails(String thumbnailImage, @Nullable String thumbnai
845849
Locator popup = Locator.tag("div").withAttribute("id", "helpDiv").descendant("img").withAttributeContaining("src", popupImage).
846850
withAttributeContaining("style", popupWidth != null ? "width:" + popupWidth : "max-width:300px");
847851
shortWait().until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#helpDiv")));
848-
String src = popup.findElement(getDriver()).getAttribute("src");
852+
String src = StringUtils.trimToEmpty(popup.findElement(getDriver()).getDomAttribute("src"));
849853

850854
fireEvent(thumbnail, SeleniumEvent.mouseout);
851855
Locator.tagWithClass("th", "labkey-selectors").findElement(getDriver()).click(); // safe out-click in the first header cell
@@ -857,7 +861,7 @@ private void validateThumbnails(String thumbnailImage, @Nullable String thumbnai
857861
else
858862
{
859863
Locator popup = Locator.tag("div").withAttribute("id", "helpDiv").descendant("img").withAttributeContaining("src", popupImage);
860-
assertTrue("Popup should not be present", !popup.existsIn(getDriver()));
864+
assertFalse("Popup should not be present", popup.existsIn(getDriver()));
861865
}
862866
}
863867

@@ -884,7 +888,7 @@ private void doTestViewEditing()
884888

885889
assertTrue("should be able to select default view", saveWindow.defaultViewRadio.isEnabled());
886890
saveWindow.defaultViewRadio.check();
887-
Window saveError = saveWindow.saveError();
891+
Window<?> saveError = saveWindow.saveError();
888892
saveError.clickButton("OK", 0);
889893
saveError.waitForClose();
890894

@@ -1004,10 +1008,8 @@ private void cleanupTable(Connection cn, String tableName) throws IOException
10041008
Object value = convertedRow.getValue(keyField);
10051009
newRow.put(keyField, value);
10061010

1007-
List<Map<String, Object>> rows = rowsByContainer.get(container);
1008-
if (rows == null)
1009-
rowsByContainer.put(container, rows = new ArrayList<>());
1010-
rows.add(newRow);
1011+
rowsByContainer.computeIfAbsent(container, k -> new ArrayList<>())
1012+
.add(newRow);
10111013
}
10121014

10131015
for (String container : rowsByContainer.keySet())
@@ -1028,8 +1030,7 @@ private void cleanupTable(Connection cn, String tableName) throws IOException
10281030
// Don't log project not found error
10291031
if (e.getStatusCode() != 404)
10301032
{
1031-
log("** Error during cleanupTable:");
1032-
e.printStackTrace(System.out);
1033+
TestLogger.info("** Error during cleanupTable:", e);
10331034
}
10341035
}
10351036
}
@@ -1076,14 +1077,10 @@ protected void createList() throws Exception
10761077
new FieldDefinition("Age", FieldDefinition.ColumnType.Integer).setDescription("Age"),
10771078
new FieldDefinition("Crazy", FieldDefinition.ColumnType.Boolean).setDescription("Crazy?")
10781079
));
1079-
listDef.create(createDefaultConnection(), getProjectName());
1080-
1081-
log("Importing some data...");
1082-
goToManageLists();
1083-
_listHelper.goToList(LIST_NAME);
1084-
_listHelper.clickImportData()
1085-
.setText(LIST_DATA)
1086-
.submit();
1080+
Connection connection = createDefaultConnection();
1081+
listDef.create(connection, getProjectName())
1082+
.getQueryHelper(connection)
1083+
.importData(LIST_DATA);
10871084
}
10881085

10891086
@LogMethod
@@ -1198,16 +1195,18 @@ private void doTestReportIcon()
11981195
File expectedIconFile = TestFileUtils.getSampleData(THUMBNAIL_FOLDER + KNITR_PEOPLE + ICON_FILENAME);
11991196
String expectedIcon = TestFileUtils.getFileContents(expectedIconFile);
12001197

1201-
String iconStyle = waitForElement(Locator.tag("img").withClass("dataview-icon").withoutClass("x4-tree-icon-parent").notHidden()).getAttribute("style");
1202-
assertTrue("Module report icon style is not as expected", iconStyle.indexOf("background-image") == 0);
1203-
String iconSrc = iconStyle.replace("background-image:url(\"", "").replace("background-image: url(\"", "").replace("\");", "");
1204-
1205-
String portPortion = 80 == WebTestHelper.getWebPort() ? "" : ":" + WebTestHelper.getWebPort();
1206-
String protocol = WebTestHelper.getTargetServer() + portPortion;
1207-
String iconData = WebTestHelper.getHttpResponse(protocol + iconSrc).getResponseBody();
1198+
WebElement img = waitForElement(Locator.tag("img").withClass("dataview-icon").withoutClass("x4-tree-icon-parent").notHidden());
1199+
String backgroundImage = StringUtils.trimToEmpty(img.getCssValue("background-image"));
1200+
Matcher matcher = Pattern.compile("^url\\(\"(.+)\"\\)$").matcher(backgroundImage);
1201+
if (!matcher.find())
1202+
{
1203+
Assert.fail("Module report icon style is not as expected: " + img.getDomAttribute("style"));
1204+
}
1205+
String iconUrl = matcher.group(1);
1206+
String iconData = WebTestHelper.getHttpResponse(iconUrl).getResponseBody();
12081207

12091208
int lengthToCompare = 3000;
1210-
int diff = new LevenshteinDistance().apply(expectedIcon.substring(0, lengthToCompare), iconData.substring(0, lengthToCompare));
1209+
int diff = LevenshteinDistance.getDefaultInstance().apply(expectedIcon.substring(0, lengthToCompare), iconData.substring(0, lengthToCompare));
12111210
assertTrue("Module report icon is not as expected, diff is " + diff, expectedIcon.equals(iconData) ||
12121211
diff <= lengthToCompare * 0.03); // Might be slightly different due to indentations, etc
12131212
}
@@ -1229,16 +1228,16 @@ private void verifyReportThumbnail(@LoggedParam String reportTitle)
12291228
WebElement reportLink = waitForElement(Locator.xpath("//a[text()='" + reportTitle + "']"));
12301229
mouseOver(reportLink);
12311230
WebElement thumbnail = waitForElement(Locator.xpath("//div[@class='thumbnail']/img").notHidden());
1232-
String thumbnailData = WebTestHelper.getHttpResponse(thumbnail.getAttribute("src")).getResponseBody();
1231+
String thumbnailData = WebTestHelper.getHttpResponse(thumbnail.getDomAttribute("src")).getResponseBody();
12331232

12341233
int lengthToCompare = 5000;
1235-
int diff = new LevenshteinDistance().apply(expectedThumbnail.substring(0, lengthToCompare), thumbnailData.substring(0, lengthToCompare));
1234+
int diff = LevenshteinDistance.getDefaultInstance().apply(expectedThumbnail.substring(0, lengthToCompare), thumbnailData.substring(0, lengthToCompare));
12361235
assertTrue("Module report thumbnail is not as expected, diff is " + diff, expectedThumbnail.equals(thumbnailData) ||
12371236
diff <= lengthToCompare * 0.03); // Might be slightly different due to indentations, etc
12381237
}
12391238

12401239
@LogMethod
1241-
private void doTestImportTemplates() throws Exception
1240+
private void doTestImportTemplates()
12421241
{
12431242
log("Testing import templates...");
12441243

@@ -1251,7 +1250,7 @@ private void doTestImportTemplates() throws Exception
12511250
assertTrue("Import message not present", isTextPresent("Please read this before you import data"));
12521251

12531252
Locator l = Locator.xpath("//select[@id='importTemplate']//option");
1254-
assertTrue("Wrong number of templates found", getElementCount(l) == 2);
1253+
assertEquals("Wrong number of templates found", 2, l.findElements(getDriver()).size());
12551254
}
12561255

12571256
@LogMethod
@@ -1401,7 +1400,7 @@ private void doTestFilterSort() throws Exception
14011400
selectResp = selectCmd.execute(cn, getProjectName());
14021401
assertEquals("Expected first row to be 2001.", 2001, selectResp.getRows().get(0).get("ModelYear"));
14031402
assertEquals("Expected first row to be 2000.", 2000, selectResp.getRows().get(1).get("ModelYear"));
1404-
assertTrue("Expected the column 'ModelId/ManufacturerId/Name' to be included based on the default view", selectResp.getColumnModel("ModelId/ManufacturerId/Name") != null);
1403+
assertNotNull("Expected the column 'ModelId/ManufacturerId/Name' to be included based on the default view", selectResp.getColumnModel("ModelId/ManufacturerId/Name"));
14051404
assertEquals("Expected to return 6 columns, based on the default view", 6, selectResp.getColumnModel().size());
14061405
}
14071406

@@ -1449,37 +1448,37 @@ private void doTestFilterSort() throws Exception
14491448
labkey.ensureRLibPath <- function(append=FALSE)
14501449
{
14511450
propValue <- labkey.getModuleProperty(baseUrl, folderPath, moduleName, propName)
1452-
\s
1451+
14531452
splits <- strsplit(propValue, '\\r\\n|\\n|\\r')
14541453
paths <- splits[[1]]
1455-
\s
1454+
14561455
if (append == TRUE)
1457-
\t.libPaths(c(paths, .libPaths()))
1456+
.libPaths(c(paths, .libPaths()))
14581457
else
1459-
\t.libPaths(c(paths[1], paths[2]))
1460-
\s
1458+
.libPaths(c(paths[1], paths[2]))
1459+
14611460
.libPaths()
14621461
}
1463-
\s
1462+
14641463
folderPath = "SimpleModuleTest Project/subfolder"
14651464
print("BEGIN-FIRST-CALL")
1466-
labkey.ensureRLibPath() \s
1465+
labkey.ensureRLibPath()
14671466
print("END-FIRST-CALL")
1468-
\s
1469-
folderPath = "SimpleModuleTest Project/subfolder2" \s
1467+
1468+
folderPath = "SimpleModuleTest Project/subfolder2"
14701469
print("BEGIN-SECOND-CALL")
14711470
labkey.ensureRLibPath()
1472-
print("END-SECOND-CALL") \s
1471+
print("END-SECOND-CALL")
14731472
1474-
folderPath = "SimpleModuleTest Project/subfolder" \s
1473+
folderPath = "SimpleModuleTest Project/subfolder"
14751474
print("BEGIN-THIRD-CALL")
14761475
labkey.ensureRLibPath(append=TRUE)
14771476
print("END-THIRD-CALL")
1478-
\s""";
1477+
""";
14791478

14801479
@LogMethod
14811480
@Test
1482-
public void testModuleProperties() throws Exception
1481+
public void testModuleProperties()
14831482
{
14841483
RReportHelper rReportHelper = new RReportHelper(this);
14851484
rReportHelper.ensureRConfig(false);
@@ -1705,6 +1704,7 @@ private void editMetadata(String schemaName, String tableName, String operations
17051704
clickButton("Save & Finish");
17061705
}
17071706

1707+
@Language("JavaScript")
17081708
private static final String vehicleMetadataJsQuery = """
17091709
function onFailure(errorInfo, options, responseObj)
17101710
{
@@ -1793,7 +1793,7 @@ private Map getColorColumnFilterGroup()
17931793
Map result = (Map)executeAsyncScript(vehicleMetadataJsQuery);
17941794
Map colorColumnFields = ((List<Map>)(((Map)result.get("metaData")).get("fields"))).get(0);
17951795

1796-
assertEquals("Column fields for column 'Color' in vehicle.Vehicles query not found!", colorColumnFields.get("name"), "Color");
1796+
assertEquals("Column fields for column 'Color' in vehicle.Vehicles query not found!", "Color", colorColumnFields.get("name"));
17971797

17981798
return (Map)((List)((Map)colorColumnFields.get("lookup")).get("filterGroups")).get(0);
17991799
}

0 commit comments

Comments
 (0)