Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bot] Fast-forward for 23.11.3 #1754

Merged
merged 3 commits into from
Dec 12, 2023
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
4 changes: 2 additions & 2 deletions modules/dumbster/src/org/labkey/dumbster/view/mailWebPart.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,9 @@ function toggleRecorder(checkbox)
<%
if (getUser().hasRootAdminPermission())
{
addHandler("emailRecordOn", "click", "toggleRecorder(this); return false;");
addHandler("emailRecordOn", "click", "toggleRecorder(this);");
%>
<input name="emailRecordOn" type="checkbox" <%=checked(recorder)%>> Record email messages sent
<input id="emailRecordOn" name="emailRecordOn" type="checkbox" <%=checked(recorder)%>> Record email messages sent
<%
}
%>
3 changes: 3 additions & 0 deletions src/org/labkey/test/BaseWebDriverTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.awaitility.Awaitility;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.JSONObject;
Expand Down Expand Up @@ -202,6 +203,8 @@ public abstract class BaseWebDriverTest extends LabKeySiteWrapper implements Cle

public BaseWebDriverTest()
{
Awaitility.pollInSameThread(); // We don't do cross thread selenium testing.

_artifactCollector = new ArtifactCollector(this);
_errorCollector = new DeferredErrorCollector(_artifactCollector);
_listHelper = new ListHelper(this);
Expand Down
63 changes: 20 additions & 43 deletions src/org/labkey/test/LabKeySiteWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.labkey.remoteapi.query.SelectRowsCommand;
import org.labkey.remoteapi.query.SelectRowsResponse;
import org.labkey.test.components.core.ProjectMenu;
import org.labkey.test.components.core.login.SetPasswordForm;
import org.labkey.test.components.dumbster.EmailRecordTable;
import org.labkey.test.components.html.SiteNavBar;
import org.labkey.test.components.ui.navigation.UserMenu;
Expand Down Expand Up @@ -411,22 +412,10 @@ public void signInShouldFail(String email, String password, String... expectedMe

protected String setInitialPassword(String user)
{
return setInitialPassword(user, PasswordUtil.getPassword());
}

// Don't call this unless you're actually testing authentication functionality
protected String setInitialPassword(String user, String password)
{
beginAt(WebTestHelper.buildURL("security", "showRegistrationEmail", Map.of("email", user)));
// Get setPassword URL from notification email.
WebElement resetLink = Locator.linkWithHref("setPassword.view").findElement(getDriver());

clickAndWait(resetLink, WAIT_FOR_PAGE);

setFormElement(Locator.id("password"), password);
setFormElement(Locator.id("password2"), password);

clickButton("Set Password");
String password = PasswordUtil.getPassword();
SetPasswordForm.goToInitialPasswordForUser(this, user)
.setNewPassword(password)
.clickSubmit();

return password;
}
Expand All @@ -453,23 +442,8 @@ protected void resetPassword(String resetUrl, String username, String newPasswor
"Your password must be at least six characters and cannot contain spaces or match your email address."
);

setFormElement(Locator.id("password"), newPassword);
setFormElement(Locator.id("password2"), newPassword);

clickButton("Set Password");
}

@LogMethod protected void changePassword(String oldPassword, @LoggedParam String password)
{
if (PasswordUtil.getUsername().equals(getCurrentUser()))
throw new IllegalArgumentException("Don't change the primary site admin user's password");

goToMyAccount();
clickButton("Change Password");

setFormElement(Locator.id("oldPassword"), oldPassword);
setFormElement(Locator.id("password"), password);
setFormElement(Locator.id("password2"), password);
new SetPasswordForm(getDriver())
.setNewPassword(newPassword);

clickButton("Set Password");
}
Expand Down Expand Up @@ -620,17 +594,23 @@ private void checkForUpgrade()
// check to see if we're the first user:
if (isTextPresent("Welcome! We see that this is your first time logging in."))
{
String email = PasswordUtil.getUsername();
bootstrapped = true;
assertTitleEquals("Account Setup");
log("Need to bootstrap");
verifyInitialUserRedirects();

log("Verify strength gauge for 'ChangePasswordAction'");
SetPasswordForm setPasswordForm = new SetPasswordForm(getDriver());
setPasswordForm.setEmail(email);
setPasswordForm.verifyPasswordStrengthGauge(email);
refresh(); // Clear form

log("Testing bad email addresses");
verifyInitialUserError(null, null, null, "Invalid email address");
verifyInitialUserError("bogus@bogus@bogus", null, null, "Invalid email address: bogus@bogus@bogus");

log("Testing bad passwords");
String email = PasswordUtil.getUsername();
verifyInitialUserError(email, null, null, "You must enter a password.");
verifyInitialUserError(email, PasswordUtil.getPassword(), null, "You must confirm your password.");
verifyInitialUserError(email, null, PasswordUtil.getPassword(), "You must enter a password.");
Expand Down Expand Up @@ -772,26 +752,23 @@ else if (getDriver().getTitle().startsWith("Sign In"))

private void verifyInitialUserError(@Nullable String email, @Nullable String password1, @Nullable String password2, @Nullable String expectedError)
{
SetPasswordForm setPasswordForm = new SetPasswordForm(getDriver());
if (null != email)
setFormElement(Locator.id("email"), email);
setPasswordForm.setEmail(email);

if (null != password1)
setFormElement(Locator.id("password"), password1);
setPasswordForm.setPassword1(password1);

if (null != password2)
setFormElement(Locator.id("password2"), password2);

clickAndWait(Locator.linkWithText("Next"), 90000); // Initial user creation blocks during upgrade script execution
setPasswordForm.setPassword2(password2);

if (null != expectedError)
{
assertEquals("Wrong error message.", expectedError, Locator.css(".labkey-error").findElement(getDriver()).getText());
setPasswordForm.clickSubmitExpectingError(expectedError);
}
else
{
WebElement element = Locator.css(".labkey-error").findElementOrNull(getDriver());
if (null != element)
fail("Unexpected error: " + element.getText());
setPasswordForm.clickSubmit(90_000); // Initial user creation blocks during upgrade script execution
}
}

Expand Down
191 changes: 191 additions & 0 deletions src/org/labkey/test/components/core/login/SetPasswordForm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package org.labkey.test.components.core.login;

import org.awaitility.Awaitility;
import org.junit.Assert;
import org.labkey.test.Locator;
import org.labkey.test.Locators;
import org.labkey.test.WebDriverWrapper;
import org.labkey.test.WebTestHelper;
import org.labkey.test.components.Component;
import org.labkey.test.components.WebDriverComponent;
import org.labkey.test.components.html.Input;
import org.labkey.test.util.LogMethod;
import org.labkey.test.util.LoggedParam;
import org.labkey.test.util.PasswordUtil;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.labkey.test.components.html.Input.Input;

/**
* core/src/org/labkey/core/login/setPassword.jsp
*/
public class SetPasswordForm extends WebDriverComponent<SetPasswordForm.ElementCache>
{
public static final String SHORT_PASSWORD = "4asdfg!"; // Only 7 characters long. 3 character types.
public static final String VERY_WEAK_PASSWORD = "3asdfghi"; // Only two character types. 8 characters long.
public static final String WEAK_PASSWORD = "Yekbal1!"; // 8 characters long. 3+ character types.
public static final String STRONG_PASSWORD = "We'reSo$tr0";
public static final String VERY_STRONG_PASSWORD = "We'reSo$tr0ng@yekbal1!";
public static final String GUIDANCE_PLACEHOLDER = "Password Strength Gauge";

private final WebElement _el;
private final WebDriver _driver;

public SetPasswordForm(WebDriver driver)
{
_el = Locator.id("setPasswordForm").waitForElement(driver, 5_000);
_driver = driver;

if (getWrapper().getCurrentRelativeURL().contains("changePassword.view") && PasswordUtil.getUsername().equals(getWrapper().getCurrentUser()))
throw new IllegalArgumentException("Don't change the primary site admin user's password");
}

// Don't use this unless you're actually testing authentication functionality
public static SetPasswordForm goToInitialPasswordForUser(WebDriverWrapper wrapper, String email)
{
wrapper.beginAt(WebTestHelper.buildURL("security", "showRegistrationEmail", Map.of("email", email)));
// Get setPassword URL from notification email.
WebElement resetLink = Locator.linkWithHref("setPassword.view").findElement(wrapper.getDriver());

wrapper.clickAndWait(resetLink, WebDriverWrapper.WAIT_FOR_PAGE);

return new SetPasswordForm(wrapper.getDriver());
}

@Override
public WebElement getComponentElement()
{
return _el;
}

@Override
public WebDriver getDriver()
{
return _driver;
}

/**
* Verify password strength guidance for various passwords
* @param ignoredSubstrings strings that should be ignored when calculating password strength (e.g. user's email)
*/
@LogMethod
public void verifyPasswordStrengthGauge(String... ignoredSubstrings)
{
List<String> substringList = new ArrayList<>();
substringList.add("");
substringList.addAll(Arrays.asList(ignoredSubstrings));

for (String substring : substringList)
{
assertPasswordGuidance(substring, substring.isEmpty() ? GUIDANCE_PLACEHOLDER : "Very Weak");
assertPasswordGuidance(WEAK_PASSWORD + substring, "Weak");
assertPasswordGuidance(VERY_WEAK_PASSWORD + substring, "Very Weak");
assertPasswordGuidance(STRONG_PASSWORD + substring, "Strong");
assertPasswordGuidance(SHORT_PASSWORD + substring, "Very Weak");
assertPasswordGuidance(VERY_STRONG_PASSWORD + substring, "Very Strong");
}
}

@LogMethod(quiet = true)
public void assertPasswordGuidance(@LoggedParam String password, @LoggedParam String expectedGuidance)
{
if (!password.isEmpty() && elementCache().strengthGuidance.getText().equals(expectedGuidance))
assertPasswordGuidance("", GUIDANCE_PLACEHOLDER); // Clear out previous guidance

setPassword1(password);
Awaitility.await().atMost(Duration.ofSeconds(2)).untilAsserted(() ->
assertEquals("Strength guidance for password", expectedGuidance, elementCache().strengthGuidance.getText()));
}

public SetPasswordForm setEmail(String email)
{
elementCache().email.set(email);

return this;
}

public SetPasswordForm setOldPassword(String oldPassword)
{
elementCache().oldPassword.set(oldPassword);

return this;
}

public SetPasswordForm setPassword1(String password1)
{
if (password1.isEmpty())
{
// `WebElement.clear()` doesn't trigger `oninput`
// Need to use this method to update strength guidance
getWrapper().actionClear(elementCache().password);
}
else
{
// Won't trigger 'oninput'
elementCache().password.clear();
// Paste to avoid triggering 'oninput' twice
getWrapper().actionPaste(elementCache().password, password1);
}

return this;
}

public SetPasswordForm setPassword2(String password2)
{
elementCache().password2.set(password2);

return this;
}

public SetPasswordForm setNewPassword(String password)
{
return setPassword1(password).setPassword2(password);
}

public void clickSubmit()
{
clickSubmit(getWrapper().getDefaultWaitForPage());
}

public void clickSubmit(int waitForPage)
{
getWrapper().clickAndWait(elementCache().submitButton, waitForPage);
getWrapper().assertNoLabKeyErrors();
}

public SetPasswordForm clickSubmitExpectingError(String expectedError)
{
getWrapper().clickAndWait(elementCache().submitButton);
Assert.assertEquals("Wrong error message", expectedError, Locators.labkeyError.waitForElement(getDriver(), 10_000).getText());

return new SetPasswordForm(getDriver());
}

@Override
protected ElementCache newElementCache()
{
return new ElementCache();
}

protected class ElementCache extends Component<?>.ElementCache
{
// For InitialUserAction
final Input email = Input(Locator.id("email"), getDriver()).findWhenNeeded(this);

// For ChangePasswordAction
final Input oldPassword = Input(Locator.id("oldPassword"), getDriver()).findWhenNeeded(this);

final WebElement password = Locator.id("password").findWhenNeeded(this);
final Input password2 = Input(Locator.id("password2"), getDriver()).findWhenNeeded(this);
final WebElement strengthGuidance = Locator.id("strengthGuidance").findWhenNeeded(this);
final WebElement submitButton = Locator.name("set").findWhenNeeded(this);
}
}
1 change: 0 additions & 1 deletion src/org/labkey/test/components/react/MultiMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,6 @@ public MultiMenuFinder withButtonIcon(String iconClass)
_locator = Locators.menuContainer().withChild(BootstrapMenu.Locators.dropdownToggle().withChild(Locator.byClass(iconClass)));
return this;
}

@Override
protected MultiMenuFinder getThis()
{
Expand Down
8 changes: 7 additions & 1 deletion src/org/labkey/test/pages/core/login/LoginConfigurePage.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ public boolean canAddSecondaryConfiguration()
return elementCache().secondaryMenuFinder.findOptional(getDriver()).isPresent();
}

public boolean isSecondaryConfOptionEnabled(String option)
{
toggleSecondaryConfiguration();
return !elementCache().addSecondaryMenu.isMenuItemDisabled(option);
}

private boolean isPrimarySelected()
{
return elementCache().panelTab1.getAttribute("aria-selected").equals("true");
Expand Down Expand Up @@ -197,7 +203,7 @@ protected class ElementCache extends LabKeyPage.ElementCache
BootstrapMenu addPrimaryMenu = primaryMenuFinder.findWhenNeeded(this);
MultiMenu.MultiMenuFinder secondaryMenuFinder = new MultiMenu.MultiMenuFinder(getDriver())
.withText("Add New Secondary Configuration").timeout(WAIT_FOR_JAVASCRIPT);
BootstrapMenu addSecondaryMenu = secondaryMenuFinder.findWhenNeeded(this);
MultiMenu addSecondaryMenu = secondaryMenuFinder.findWhenNeeded(this);

WebElement globalSettingsPanel()
{
Expand Down
1 change: 1 addition & 0 deletions src/org/labkey/test/pages/user/UpdateUserDetailsPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public String getField(String fieldName)
public void clickSubmit()
{
clickAndWait(elementCache().submitButton);
assertNoLabKeyErrors();
}

@Override
Expand Down
6 changes: 1 addition & 5 deletions src/org/labkey/test/tests/UserPermissionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,7 @@ private void userPermissionRightsTest()
_permissionsHelper.createPermissionsGroup(GAMMA_ADMIN_GROUP_NAME);
_permissionsHelper.setPermissions(GAMMA_ADMIN_GROUP_NAME, "Project Administrator");
createUserInProjectForGroup(GAMMA_PROJECT_ADMIN_USER, PERM_PROJECT_NAME, GAMMA_ADMIN_GROUP_NAME, true);
clickLinkWithTextNoTarget("here");
clickAndWait(Locator.linkContainingText("setPassword.view"));
setFormElement(Locator.id("password"), PasswordUtil.getPassword());
setFormElement(Locator.id("password2"), PasswordUtil.getPassword());
clickButton("Set Password");
setInitialPassword(GAMMA_PROJECT_ADMIN_USER);
signOut();
signIn(GAMMA_PROJECT_ADMIN_USER);
clickProject(PERM_PROJECT_NAME);
Expand Down
Loading