Skip to content
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
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ lookfirstSardineVersion=5.13

jettyVersion=12.1.5

seleniumVersion=4.40.0
seleniumVersion=4.41.0

mockserverNettyVersion=5.15.0

Expand Down
10 changes: 10 additions & 0 deletions src/org/labkey/test/BaseWebDriverTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hc.core5.http.HttpStatus;
import org.awaitility.Awaitility;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -2734,6 +2735,15 @@ private File clickExportImageIcon(String chartParentCls, int chartIndex, Locator
}
}

public void verifyImagePopupInGrid(File imageFile)
{
mouseOver(Locator.xpath("//img[contains(@title, '" + imageFile.getName() + "')]"));
longWait().until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#helpDiv")));
String src = Locator.xpath("//div[@id='helpDiv']//img[contains(@src, 'download')]").findElement(getDriver()).getAttribute("src");
assertTrue("Wrong image in popup: " + src, src.contains(imageFile.getName()));
assertEquals("Bad response from image pop-up", HttpStatus.SC_OK, WebTestHelper.getHttpResponse(src).getResponseCode());
}

public List<Map<String, Object>> loadTsv(File tsv)
{
try (TabLoader loader = new TabLoader(tsv, true))
Expand Down
19 changes: 4 additions & 15 deletions src/org/labkey/test/WebDriverWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import org.labkey.test.util.TextSearcher;
import org.labkey.test.util.TextSearcher.TextTransformers;
import org.labkey.test.util.Timer;
import org.labkey.test.util.selenium.JavascriptExecutorWrapper;
import org.labkey.test.util.selenium.ScrollUtils;
import org.labkey.test.util.selenium.WebDriverUtils;
import org.openqa.selenium.Alert;
Expand Down Expand Up @@ -539,11 +540,7 @@ public Object executeScript(@Language("JavaScript") String script, Object... arg
*/
public <T> T executeScript(@Language("JavaScript") String script, Class<T> expectedResultType, Object... arguments)
{
Object o = executeScript(script, arguments);
if (o != null && !expectedResultType.isAssignableFrom(o.getClass()))
Assert.fail("Script return wrong type. Expected '" + expectedResultType.getSimpleName() + "'. Got: " + o.getClass().getName() + ". Result: " + o);

return (T) o;
return new JavascriptExecutorWrapper(getDriver()).executeScript(script, expectedResultType, arguments);
}

/**
Expand All @@ -552,20 +549,12 @@ public <T> T executeScript(@Language("JavaScript") String script, Class<T> expec
*/
public Object executeAsyncScript(@Language("JavaScript") String script, Object... arguments)
{
script = "var callback = arguments[arguments.length - 1];\n" + // See WebDriver documentation for details on injected callback
"try {" +
script +
"} catch (error) { callback(error); }"; // ensure that the callback is invoked when an exception would otherwise prevent it
return ((JavascriptExecutor) getDriver()).executeAsyncScript(script, arguments);
return new JavascriptExecutorWrapper(getDriver()).executeAsyncScript(script, arguments);
}

public <T> T executeAsyncScript(@Language("JavaScript") String script, Class<T> expectedResultType, Object... arguments)
{
Object o = executeAsyncScript(script, arguments);
if (o != null && !expectedResultType.isAssignableFrom(o.getClass()))
Assert.fail("Script return wrong type. Expected '" + expectedResultType.getSimpleName() + "'. Got: " + o.getClass().getName() + ". Result: " + o);

return (T) o;
return new JavascriptExecutorWrapper(getDriver()).executeAsyncScript(script, expectedResultType, arguments);
}

@LogMethod(quiet = true)
Expand Down
2 changes: 2 additions & 0 deletions src/org/labkey/test/components/domain/DomainFieldRow.java
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,8 @@ public DomainFieldRow clickRemoveOntologyConcept()

public void setAllowMultipleSelections(Boolean allowMultipleSelections)
{
WebDriverWrapper.waitFor(() -> elementCache().allowMultipleSelectionsCheckbox.isDisplayed(),
"Allow Multiple Selections checkbox did not become visible", 2000);
elementCache().allowMultipleSelectionsCheckbox.set(allowMultipleSelections);
}

Expand Down
21 changes: 20 additions & 1 deletion src/org/labkey/test/components/list/ManageListsGrid.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,30 @@ public File exportSelectedLists()

public BeginPage deleteSelectedLists()
{
clickHeaderButtonAndWait("Delete");
if (getHeaderButton("Delete").getAttribute("class").contains("labkey-down-arrow"))
clickHeaderMenu("Delete", true, "Delete List");
else
clickHeaderButtonAndWait("Delete");

ConfirmDeletePage confirmPage = new ConfirmDeletePage(getDriver());
return confirmPage.confirmDelete();
}

public BeginPage deleteAllDataFromSelectedLists()
{
clickHeaderMenu("Delete", true, "Delete All Data from List");
ConfirmDeletePage confirmPage = new ConfirmDeletePage(getDriver(), "Confirm Delete All Data");
return confirmPage.confirmDelete();
}

public ManageListsGrid selectLists(List<String> listNames)
{
for (String listName : listNames)
checkCheckbox(getRowIndex("Name", listName));

return this;
}

public List<String> getListNames()
{
return getColumnDataAsText("Name");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public WebElement getComponentElement()

public Boolean isLoaded()
{
return getComponentElement().isDisplayed() &&
return WebElementUtils.checkVisibility(getComponentElement()) &&
!Locators.loadingGrid.existsIn(this) &&
!Locators.spinner.existsIn(this) &&
(Locator.tag("td").existsIn(this) ||
Expand Down
10 changes: 9 additions & 1 deletion src/org/labkey/test/pages/list/ConfirmDeletePage.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,17 @@

public class ConfirmDeletePage extends LabKeyPage<ConfirmDeletePage.ElementCache>
{
private String _deleteBtnText;

public ConfirmDeletePage(WebDriver driver)
{
this(driver, "Confirm Delete");
}

public ConfirmDeletePage(WebDriver driver, String deleteBtnText)
{
super(driver);
_deleteBtnText = deleteBtnText;
}

public BeginPage confirmDelete()
Expand All @@ -27,6 +35,6 @@ protected ElementCache newElementCache()

protected class ElementCache extends LabKeyPage<?>.ElementCache
{
WebElement deleteButton = Locator.lkButton("Confirm Delete").findWhenNeeded(this);
WebElement deleteButton = Locator.lkButton(_deleteBtnText == null ? "Confirm Delete" : _deleteBtnText).findWhenNeeded(this);
}
}
5 changes: 3 additions & 2 deletions src/org/labkey/test/tests/AbstractAssayTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import static org.labkey.test.params.FieldDefinition.DOMAIN_TRICKY_CHARACTERS;
import static org.labkey.test.util.PermissionsHelper.EDITOR_ROLE;
import static org.labkey.test.util.PermissionsHelper.READER_ROLE;
import static org.labkey.test.util.PermissionsHelper.SEE_AUDIT_LOG_SITE_ROLE;

/**
* @deprecated TODO: Move shared functionality to a Helper class
Expand Down Expand Up @@ -209,8 +210,8 @@ protected void setupEnvironment()

//add a PI user to that group
permissionsHelper.addUserToProjGroup(TEST_ASSAY_USR_PI1, getProjectName(), TEST_ASSAY_GRP_PIS);
// give the PI user "CanSeeAuditLog" permission
permissionsHelper.setSiteRoleUserPermissions(TEST_ASSAY_USR_PI1, "See Audit Log Events");
// give the PI user site "CanSeeAuditLog" permission
permissionsHelper.setSiteRoleUserPermissions(TEST_ASSAY_USR_PI1, SEE_AUDIT_LOG_SITE_ROLE);

//add a lab tech user to the Users group
permissionsHelper.addUserToProjGroup(TEST_ASSAY_USR_TECH1, getProjectName(), TEST_ASSAY_GRP_USERS);
Expand Down
54 changes: 36 additions & 18 deletions src/org/labkey/test/tests/AuditLogTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.labkey.test.util.Log4jUtils;
import org.labkey.test.util.PermissionsHelper;
import org.labkey.test.util.PortalHelper;
import org.labkey.test.util.SearchHelper;
import org.labkey.test.util.UIUserHelper;

import java.io.BufferedReader;
Expand All @@ -64,11 +65,13 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.labkey.test.util.PasswordUtil.getUsername;
import static org.labkey.test.util.PermissionsHelper.AUTHOR_ROLE;
import static org.labkey.test.util.PermissionsHelper.EDITOR_ROLE;
import static org.labkey.test.util.PermissionsHelper.FOLDER_ADMIN_ROLE;
import static org.labkey.test.util.PermissionsHelper.PROJECT_ADMIN_ROLE;
import static org.labkey.test.util.PasswordUtil.getUsername;
import static org.labkey.test.util.PermissionsHelper.SEE_AUDIT_LOG_FOLDER_ROLE;
import static org.labkey.test.util.PermissionsHelper.SEE_AUDIT_LOG_SITE_ROLE;

@Category({Daily.class, Hosting.class})
@BaseWebDriverTest.ClassTimeout(minutes = 9)
Expand All @@ -79,21 +82,18 @@ public class AuditLogTest extends BaseWebDriverTest
public static final String QUERY_UPDATE_EVENT = "Query update events";
public static final String PROJECT_AUDIT_EVENT = "Project and Folder events";
public static final String ASSAY_AUDIT_EVENT = "Link to Study events";
public static final String COMMENT_COLUMN = "Comment";

private static final String AUDIT_TEST_USER = "audit_user1@auditlog.test";
private static final String AUDIT_TEST_USER2 = "audit_user2@auditlog.test";
private static final String AUDIT_TEST_USER3 = "audit_user3@auditlog.test";

private static final String AUDIT_SECURITY_GROUP = "Testers";

private static final String AUDIT_TEST_PROJECT = "AuditVerifyTest";
private static final String AUDIT_DETAILED_TEST_PROJECT = "AuditDetailedLogTest";
private static final String AUDIT_TEST_SUBFOLDER = "AuditVerifyTest_Subfolder";
private static final String AUDIT_PROPERTY_EVENTS_PROJECT = "AuditDomainPropertyEvents";

final String DOMAIN_PROPERTY_LOG_NAME = "Domain property events";

public static final String COMMENT_COLUMN = "Comment";
private static final String DOMAIN_PROPERTY_LOG_NAME = "Domain property events";
private static final String SEARCH_TERM = "doesn't matter";

private final ApiPermissionsHelper permissionsHelper = new ApiPermissionsHelper(this);
private final AuditLogHelper _auditLogHelper = new AuditLogHelper(this);
Expand Down Expand Up @@ -377,19 +377,37 @@ protected void canSeeAuditLogTest()
createUserWithPermissions(AUDIT_TEST_USER, AUDIT_TEST_PROJECT, EDITOR_ROLE);
createUserWithPermissions(AUDIT_TEST_USER2, AUDIT_TEST_PROJECT, PROJECT_ADMIN_ROLE);

// Do a search to ensure an audit entry in /home
clickProject("Home");
new SearchHelper(this).searchFor(SEARCH_TERM);
goToProjectHome();

// signed in as an admin so we should see rows here
verifyAuditQueries(true);
verifyAuditQueries(true, getProjectName());

// signed in as an editor should not show any rows for audit query links
impersonate(AUDIT_TEST_USER);
verifyAuditQueries(false);
verifyAuditQueries(false, getProjectName());
verifyAuditQueries(false, "Home");
stopImpersonating();

// Grant the "See Audit Log Events" folder role to our audit user in the project and verify we see audit
// information in this project but not /Home. We pass the fully qualified classnames in the next few calls to
// disambiguate the root role from the folder role.
permissionsHelper.addMemberToRole(AUDIT_TEST_USER, SEE_AUDIT_LOG_FOLDER_ROLE, PermissionsHelper.MemberType.user, getProjectName());
impersonate(AUDIT_TEST_USER);
verifyAuditQueries(true, getProjectName());
verifyAuditQueries(false, "Home");
stopImpersonating();
permissionsHelper.removeUserRoleAssignment(AUDIT_TEST_USER, SEE_AUDIT_LOG_FOLDER_ROLE, getProjectName());

// now grant CanSeeAuditLog permission to our audit user and verify
// we see audit information
permissionsHelper.setSiteRoleUserPermissions(AUDIT_TEST_USER, "See Audit Log Events");
// Grant the "See Audit Log Events" root role to our audit user and verify we see audit information in this
// project and in /Home
permissionsHelper.setSiteRoleUserPermissions(AUDIT_TEST_USER, SEE_AUDIT_LOG_SITE_ROLE);
impersonate(AUDIT_TEST_USER);
verifyAuditQueries(true);
verifyAuditQueries(true, getProjectName());
ExecuteQueryPage.beginAt(this, "Home", "auditLog", "SearchAuditEvent");
verifyAuditQueryEvent(this, "Query", SEARCH_TERM, 1);

// cleanup
stopImpersonating();
Expand Down Expand Up @@ -482,7 +500,7 @@ public void testDetailedQueryUpdateAuditLog() throws IOException, CommandExcepti
//then create model (which has detailed audit log level)
InsertRowsCommand insertCmd2 = new InsertRowsCommand("vehicle", "models");
rowMap = new HashMap<>();
rowMap.put("manufacturerId", resp1.getRows().get(0).get("rowid"));
rowMap.put("manufacturerId", resp1.getRows().getFirst().get("rowid"));
rowMap.put("name", "Soul");
insertCmd2.addRow(rowMap);
insertCmd2.execute(cn, AUDIT_DETAILED_TEST_PROJECT);
Expand Down Expand Up @@ -535,17 +553,17 @@ protected void verifyListAuditLogQueries(Visibility v)
verifyAuditQueryEvent(this, "List", "Child List", 1, canSeeChild(v));
}

protected void verifyAuditQueries(boolean canSeeAuditLog)
protected void verifyAuditQueries(boolean canSeeAuditLog, String containerPath)
{
ExecuteQueryPage.beginAt(this, getProjectName(), "auditLog", "ContainerAuditEvent");
ExecuteQueryPage.beginAt(this, containerPath, "auditLog", "ContainerAuditEvent");
if (canSeeAuditLog)
verifyAuditQueryEvent(this, COMMENT_COLUMN, AUDIT_TEST_PROJECT + " was created", 1);
else
assertTextPresent("No data to show.");

ExecuteQueryPage.beginAt(this, getProjectName(), "auditLog", "GroupAuditEvent");
ExecuteQueryPage.beginAt(this, containerPath, "auditLog", "GroupAuditEvent");
if (canSeeAuditLog)
verifyAuditQueryEvent(this, COMMENT_COLUMN, "The user " + AUDIT_TEST_USER + " was assigned to the security role Editor.", 1);
verifyAuditQueryEvent(this, COMMENT_COLUMN, "The user " + AUDIT_TEST_USER + " was assigned to the security role Editor.", 4);
else
assertTextPresent("No data to show.");
}
Expand Down
13 changes: 12 additions & 1 deletion src/org/labkey/test/tests/GpatAssayTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.labkey.test.util.EscapeUtil;
import org.labkey.test.util.LogMethod;
import org.labkey.test.util.LoggedParam;
import org.labkey.test.util.RReportHelper;
import org.labkey.test.util.TestDataGenerator;
import org.labkey.test.util.core.webdav.WebDavUploadHelper;
import org.openqa.selenium.WebElement;
Expand Down Expand Up @@ -72,11 +73,13 @@ public class GpatAssayTest extends BaseWebDriverTest
private static final String ASSAY_NAME_FNA = "FASTA Assay";
private static final String ASSAY_NAME_FNA_MULTIPLE = "FASTA Assay - Multiple file upload";
private static final String ASSAY_NAME_FNA_MULTIPLE_SINGLE_INPUT = "FASTA Assay - Multiple file single input upload";
private static final File RTRANSFORM_SCRIPT_FILE_NOOP = TestFileUtils.getSampleData("qc/noopTransform.R");

@BeforeClass
public static void doSetup()
{
GpatAssayTest init = getCurrentTest();
new RReportHelper(init).ensureRConfig();
init._containerHelper.createProject(init.getProjectName(), "Assay");
init.goToProjectHome();
}
Expand Down Expand Up @@ -256,6 +259,14 @@ private void importFastaGpatAssay(File fnaFile, String assayName)
clickButton("Save and Finish", defaultWaitForPage);
}

// GitHub Issue #875: Optionally add transform scripts in GPAT assay design to test code path with and without transform script
private void randomlyAddTransformScript(ReactAssayDesignerPage assayDesignerPage)
{
boolean shouldAddTransformScript = TestDataGenerator.randomBoolean("whether to add transform script in assay design");
if (shouldAddTransformScript)
assayDesignerPage.addTransformScript(RTRANSFORM_SCRIPT_FILE_NOOP);
}

@LogMethod
private ReactAssayDesignerPage startCreateGpatAssay(File dataFile, @LoggedParam String assayName)
{
Expand All @@ -265,9 +276,9 @@ private ReactAssayDesignerPage startCreateGpatAssay(File dataFile, @LoggedParam
_fileBrowserHelper.importFile(dataFile.getName(), "Create New Standard Assay Design");

ReactAssayDesignerPage assayDesignerPage = new ReactAssayDesignerPage(getDriver());

if (assayName != null)
assayDesignerPage.setName(assayName);
randomlyAddTransformScript(assayDesignerPage);
return assayDesignerPage;
}

Expand Down
8 changes: 2 additions & 6 deletions src/org/labkey/test/tests/InlineImagesListTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,7 @@ public final void testList() throws Exception
// Mouse over the logo, migh help with the following mouse over the image.
mouseOver(Locator.tagWithAttributeContaining("img", "src", "logo.image"));
sleep(500);
mouseOver(Locator.xpath("//img[contains(@title, '" + LRG_PNG_FILE.getName() + "')]"));
longWait().until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#helpDiv")));
String src = Locator.xpath("//div[@id='helpDiv']//img[contains(@src, 'download')]").findElement(getDriver()).getAttribute("src");
assertTrue("Wrong image in popup: " + src, src.contains(LRG_PNG_FILE.getName()));
assertEquals("Bad response from image pop-up", HttpStatus.SC_OK, WebTestHelper.getHttpResponse(src).getResponseCode());
verifyImagePopupInGrid(LRG_PNG_FILE);

// Commenting out for now. There is a random behavior where sometimes the thumbnail image will not show up when you move from one cell to another.
/*
Expand Down Expand Up @@ -303,7 +299,7 @@ public final void testList() throws Exception
sleep(500);
mouseOver(Locator.xpath("//img[contains(@title, '" + LRG_PNG_FILE.getName() + "')]"));
shortWait().until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#helpDiv")));
src = Locator.xpath("//div[@id='helpDiv']//img[contains(@src, 'download')]").findElement(getDriver()).getAttribute("src");
var src = Locator.xpath("//div[@id='helpDiv']//img[contains(@src, 'download')]").findElement(getDriver()).getAttribute("src");
assertTrue("Wrong image in popup: " + src, src.contains(LRG_PNG_FILE.getName()));
assertEquals("Bad response from image pop-up", HttpStatus.SC_OK, WebTestHelper.getHttpResponse(src).getResponseCode());

Expand Down
5 changes: 5 additions & 0 deletions src/org/labkey/test/tests/ReportSharingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.labkey.test.categories.Reports;
import org.labkey.test.util.ApiPermissionsHelper;
import org.labkey.test.util.DataRegionTable;
import org.labkey.test.util.OptionalFeatureHelper;
import org.labkey.test.util.RReportHelper;

import java.util.Arrays;
Expand All @@ -50,6 +51,8 @@ public class ReportSharingTest extends BaseWebDriverTest
@Override
protected void doCleanup(boolean afterTest) throws TestTimeoutException
{
OptionalFeatureHelper.resetOptionalFeature(createDefaultConnection(), "rReportCustomSharing");

_containerHelper.deleteProject(getProjectName(),afterTest);
_userHelper.deleteUsers(false, USER_DEV,USER_EDITOR,USER_NON_EDITOR);
}
Expand All @@ -63,6 +66,8 @@ public static void setupProject()

private void doSetup()
{
OptionalFeatureHelper.setOptionalFeature(createDefaultConnection(), "rReportCustomSharing", true);

_rReportHelper.ensureRConfig();

_containerHelper.createProject(getProjectName(), null);
Expand Down
Loading
Loading