diff --git a/src/org/labkey/test/LabKeySiteWrapper.java b/src/org/labkey/test/LabKeySiteWrapper.java index e0a9c51281..62b26da729 100644 --- a/src/org/labkey/test/LabKeySiteWrapper.java +++ b/src/org/labkey/test/LabKeySiteWrapper.java @@ -117,9 +117,9 @@ public enum ProductKey { sampleManagerStarter, sampleManagerProfessional, - labkeyLims, limsStarter, limsEnterprise, + biologics, } public boolean isGuestModeTest() diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index 27e2aaafc9..1effae6b41 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -3088,6 +3088,35 @@ public void dragAndDrop(WebElement fromEl, int xOffset, int yOffset) builder.clickAndHold(fromEl).moveByOffset(xOffset + 1, yOffset + 1).release().build().perform(); } + /** + * Reorder a drag-and-drop list with the keyboard instead of the mouse: focus the drag handle, Space to lift, + * one Arrow per step, Space to drop. Required for lists built on '@hello-pangea/dnd' (auth configurations, + * domain designer, field selection). + * + * @param dragHandle Element carrying the library's drag handle props; must be focusable. + * @param steps Positions to move; negative moves up, positive moves down. + */ + public void keyboardDragAndDrop(WebElement dragHandle, int steps) + { + dragHandle.sendKeys(Keys.SPACE); + + Actions drag = new Actions(getDriver()).pause(Duration.ofMillis(400)); + Keys arrow = steps < 0 ? Keys.ARROW_UP : Keys.ARROW_DOWN; + for (int i = 0; i < Math.abs(steps); i++) + drag.sendKeys(arrow).pause(Duration.ofMillis(300)); + drag.sendKeys(Keys.SPACE).perform(); + } + + /** + * @see #keyboardDragAndDrop(WebElement, int) + * @param dragHandle Drag handle of the element to move. + * @param target Drag handle of a sibling element to move it to. + */ + public void keyboardDragAndDrop(WebElement dragHandle, WebElement target) + { + keyboardDragAndDrop(dragHandle, getElementIndex(target) - getElementIndex(dragHandle)); + } + // This is useful when making a draggin selection in a plot, and there may be many elements ontop of the one you want. public void dragAndDrop(int xOffset, int yOffset) { diff --git a/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java b/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java index 583bb3098d..f8f0dda716 100644 --- a/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java +++ b/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java @@ -530,7 +530,7 @@ public FieldSelectionDialog repositionField(FieldKey fieldToMove, FieldKey targe int target = indexOfFieldKey(order, targetField); int to = beforeTarget ? (from < target ? target - 1 : target) : (from < target ? target : target + 1); - keyboardReorder(elementCache().findDragHandle(fieldToMove), to - from); + getWrapper().keyboardDragAndDrop(elementCache().findDragHandle(fieldToMove), to - from); WebDriverWrapper.waitFor(() -> { List now = selectedFieldKeys(); @@ -540,25 +540,6 @@ public FieldSelectionDialog repositionField(FieldKey fieldToMove, FieldKey targe return this; } - /** - * Reorder a row via the keyboard controls: focus the handle, Space to lift, one Arrow per - * step, Space to drop. (Mouse drag is unreliable with the library's sensor.) - * - * @param dragHandle The row's drag handle. - * @param steps Positions to move; negative moves up, positive moves down. - */ - private void keyboardReorder(WebElement dragHandle, int steps) - { - getWrapper().scrollIntoView(dragHandle); - getWrapper().executeScript("arguments[0].focus();", dragHandle); - - Actions drag = new Actions(getDriver()).sendKeys(Keys.SPACE).pause(Duration.ofMillis(400)); // lift - Keys arrow = steps < 0 ? Keys.ARROW_UP : Keys.ARROW_DOWN; - for (int i = 0; i < Math.abs(steps); i++) - drag.sendKeys(arrow).pause(Duration.ofMillis(300)); - drag.sendKeys(Keys.SPACE).perform(); // drop - } - /** * Get the 'data-fieldkey' values of the selected fields, in display order. * diff --git a/src/org/labkey/test/pages/core/login/LoginConfigRow.java b/src/org/labkey/test/pages/core/login/LoginConfigRow.java index 2f840381e8..42059113e0 100644 --- a/src/org/labkey/test/pages/core/login/LoginConfigRow.java +++ b/src/org/labkey/test/pages/core/login/LoginConfigRow.java @@ -72,6 +72,11 @@ public boolean canEdit() return elementCache().editButtonLoc.existsIn(this); } + public WebElement getDragHandle() + { + return elementCache().dragHandle; + } + @Override public WebElement getComponentElement() { @@ -93,6 +98,9 @@ protected ElementCache newElementCache() protected class ElementCache extends Component.ElementCache { + final WebElement dragHandle = Locator.xpath("ancestor::div") + .withAttribute("data-rfd-drag-handle-draggable-id").findWhenNeeded(this); + final WebElement baseFieldsElement = Locator.tagWithClass("div", "domain-row-base-fields").findWhenNeeded(this); final WebElement description = Locator.tagWithClass("div", "description").findWhenNeeded(baseFieldsElement); final WebElement details = Locator.tagWithClass("div", "details").findWhenNeeded(baseFieldsElement); diff --git a/src/org/labkey/test/tests/DataViewsPermissionsTest.java b/src/org/labkey/test/tests/DataViewsPermissionsTest.java index 183b2ed313..10169df09e 100644 --- a/src/org/labkey/test/tests/DataViewsPermissionsTest.java +++ b/src/org/labkey/test/tests/DataViewsPermissionsTest.java @@ -24,6 +24,7 @@ import org.labkey.test.components.html.BootstrapMenu; import org.labkey.test.util.Ext4Helper; import org.labkey.test.util.PortalHelper; +import org.labkey.test.util.TestUser; import static org.junit.Assert.assertTrue; import static org.labkey.test.util.PermissionsHelper.AUTHOR_ROLE; @@ -33,8 +34,8 @@ @BaseWebDriverTest.ClassTimeout(minutes = 10) public class DataViewsPermissionsTest extends StudyBaseTest { - public static final String AUTHOR_USER = "dvp_author@dataviews.test"; - public static final String EDITOR_USER = "dvp_editor@dataviews.test"; + public static final TestUser AUTHOR_USER = new TestUser("dvp_author@dataviews.test"); + public static final TestUser EDITOR_USER = new TestUser("dvp_editor@dataviews.test"); private final PortalHelper portalHelper = new PortalHelper(this); @Override @@ -61,6 +62,9 @@ protected void doCreateSteps() { importStudy(); + AUTHOR_USER.create(this); + EDITOR_USER.create(this); + clickFolder(getFolderName()); portalHelper.addWebPart("Data Views"); portalHelper.enterAdminMode(); @@ -79,13 +83,13 @@ protected void doCreateSteps() _permissionsHelper.createPermissionsGroup("Editor Group"); _permissionsHelper.assertPermissionSetting("Editor Group", "No Permissions"); _permissionsHelper.setPermissions("Editor Group", EDITOR_ROLE); - createUserInProjectForGroup(EDITOR_USER, "StudyVerifyProject", "Editor Group", false); + addUserToProjectGroup(EDITOR_USER, "StudyVerifyProject", "Editor Group", false); clickFolder(getFolderName()); _permissionsHelper.enterPermissionsUI(); _permissionsHelper.createPermissionsGroup("Author Group"); _permissionsHelper.assertPermissionSetting("Author Group", "No Permissions"); _permissionsHelper.setPermissions("Author Group", AUTHOR_ROLE); - createUserInProjectForGroup(AUTHOR_USER, "StudyVerifyProject", "Author Group", false); + addUserToProjectGroup(AUTHOR_USER, "StudyVerifyProject", "Author Group", false); clickFolder(getFolderName()); clickTab("Manage"); @@ -113,7 +117,6 @@ protected void doCreateSteps() clickButton("Create View", defaultWaitForPage); clickFolder(getFolderName()); portalHelper.removeWebPart("Views"); - click(Locator.tag("a").withAttributeContaining("href", "editDataViews")); openEditPanel("Report 1"); //_ext4Helper.selectRadioButton ("Visibility","Hidden"); _ext4Helper.uncheckCheckbox("Shared"); @@ -121,17 +124,15 @@ protected void doCreateSteps() _ext4Helper.clickWindowButton("Report 1","Save",0,0); _ext4Helper.waitForMaskToDisappear(); clickFolder(getFolderName()); - click(Locator.tag("a").withAttributeContaining("href", "editDataViews")); openEditPanel("Report 2"); - _ext4Helper.selectComboBoxItem("Author", _userHelper.getDisplayNameForEmail(AUTHOR_USER)); + _ext4Helper.selectComboBoxItem("Author", AUTHOR_USER.getUserDisplayName()); _ext4Helper.checkCheckbox("Shared"); sleep(1000); _ext4Helper.clickWindowButton("Report 2","Save",0,0); _ext4Helper.waitForMaskToDisappear(); clickFolder(getFolderName()); - click(Locator.tag("a").withAttributeContaining("href", "editDataViews")); openEditPanel("Report 3"); - _ext4Helper.selectComboBoxItem("Author", _userHelper.getDisplayNameForEmail(EDITOR_USER)); + _ext4Helper.selectComboBoxItem("Author", EDITOR_USER.getUserDisplayName()); _ext4Helper.checkCheckbox("Shared"); sleep(1000); _ext4Helper.clickWindowButton("Report 3","Save",0,0); @@ -139,19 +140,17 @@ protected void doCreateSteps() } @Override - protected void doVerifySteps() + protected void doVerifySteps() throws Exception { - impersonate(EDITOR_USER); - click(Locator.tag("a").withAttributeContaining("href", "editDataViews")); + EDITOR_USER.impersonate(true); openEditPanel("Report 4"); sleep(1000); _ext4Helper.clickWindowButton("Report 4", "Save", 0, 0); _ext4Helper.waitForMaskToDisappear(); - stopImpersonating(); + EDITOR_USER.stopImpersonating(true); navigateToFolder("StudyVerifyProject", getFolderName()); - sleep(500); - impersonate(AUTHOR_USER); + AUTHOR_USER.impersonate(true); PortalHelper portalHelper1 = new PortalHelper(this); portalHelper1.clickWebpartMenuItem("Data Views", true, "Add Report", "Link Report"); setFormElement(Locator.name("viewName"), "Report 5"); @@ -159,7 +158,6 @@ protected void doVerifySteps() sleep(1000); clickButton("Save", defaultWaitForPage); - click(Locator.tag("a").withAttributeContaining("href", "editDataViews")); openEditPanel("Report 5"); sleep(1000); _ext4Helper.clickWindowButton("Report 5", "Save", 0, 0); @@ -168,8 +166,13 @@ protected void doVerifySteps() verifyMineCheckbox(); } + /** + * Put the Data Views webpart into edit mode and open the edit dialog for a single view. + */ private void openEditPanel(String itemName) { + waitForElement(Locators.itemLink()); + click(Locator.tag("a").withAttributeContaining("href", "editDataViews")); waitAndClick(Locators.editViewsLink(itemName)); waitForElement(Ext4Helper.Locators.window(itemName)); } @@ -199,11 +202,16 @@ private void waitForItemCount(String errMsg, int expectedCount) private int visibleItemCount() { - return getElementCount(Locator.tagWithClass("a", "x4-tree-node-text").notHidden()); + return getElementCount(Locators.itemLink().notHidden()); } public static class Locators { + static Locator.XPathLocator itemLink() + { + return Locator.tagWithClass("a", "x4-tree-node-text"); + } + static Locator.XPathLocator editViewsLink(String dataset) { return Locator.tag("tr").withClass("x4-grid-tree-node-leaf").withDescendant(Locator.xpath("td/div/a[normalize-space()="+Locator.xq(dataset)+"]")).append("//span").withClass("edit-views-link"); @@ -221,7 +229,7 @@ static Locator.XPathLocator expanderForUncategorized() } } - private void createUserInProjectForGroup(String userName, String projectName, String groupName, boolean sendEmail) + private void addUserToProjectGroup(TestUser user, String projectName, String groupName, boolean sendEmail) { if (isElementPresent(Locator.permissionRendered())) { @@ -230,7 +238,7 @@ private void createUserInProjectForGroup(String userName, String projectName, St } _permissionsHelper.enterPermissionsUI(); _permissionsHelper.clickManageGroup(groupName); - setFormElement(Locator.name("names"), userName); + setFormElement(Locator.name("names"), user.getEmail()); if (!sendEmail) uncheckCheckbox(Locator.checkboxByName("sendEmail")); clickButton("Update Group Membership");