use of org.openqa.selenium.htmlunit.HtmlUnitDriver in project keycloak by keycloak.
the class RequiredActionsTest method testBarcodeOtp.
private void testBarcodeOtp() throws Exception {
// HtmlUnit browser cannot take screenshots
assumeFalse(driver instanceof HtmlUnitDriver);
TakesScreenshot screenshotDriver = (TakesScreenshot) driver;
QRCodeReader qrCodeReader = new QRCodeReader();
initiateRequiredAction(otpSetupPage);
otpSetupPage.localeDropdown().selectAndAssert(CUSTOM_LOCALE_NAME);
otpSetupPage.clickManualMode();
otpSetupPage.clickBarcodeMode();
assertTrue(otpSetupPage.isBarcodePresent());
assertFalse(otpSetupPage.isSecretKeyPresent());
assertTrue(otpSetupPage.feedbackMessage().isWarning());
assertEquals("You need to set up Mobile Authenticator to activate your account.", otpSetupPage.feedbackMessage().getText());
// empty input
otpSetupPage.submit();
assertTrue(otpSetupPage.feedbackMessage().isError());
assertEquals("Please specify authenticator code.", otpSetupPage.feedbackMessage().getText());
// take a screenshot of the QR code
byte[] screenshot = screenshotDriver.getScreenshotAs(OutputType.BYTES);
BufferedImage screenshotImg = ImageIO.read(new ByteArrayInputStream(screenshot));
BinaryBitmap screenshotBinaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(screenshotImg)));
Result qrCode = qrCodeReader.decode(screenshotBinaryBitmap);
// parse the QR code string
Pattern qrUriPattern = Pattern.compile("^otpauth:\\/\\/(?<type>.+)\\/(?<realm>.+):(?<user>.+)\\?secret=(?<secret>.+)&digits=(?<digits>.+)&algorithm=(?<algorithm>.+)&issuer=(?<issuer>.+)&(?:period=(?<period>.+)|counter=(?<counter>.+))$");
Matcher qrUriMatcher = qrUriPattern.matcher(qrCode.getText());
assertTrue(qrUriMatcher.find());
// extract data
String type = qrUriMatcher.group("type");
String realm = qrUriMatcher.group("realm");
String user = qrUriMatcher.group("user");
String secret = qrUriMatcher.group("secret");
int digits = Integer.parseInt(qrUriMatcher.group("digits"));
String algorithm = qrUriMatcher.group("algorithm");
String issuer = qrUriMatcher.group("issuer");
Integer period = type.equals(TOTP) ? Integer.parseInt(qrUriMatcher.group("period")) : null;
Integer counter = type.equals(HOTP) ? Integer.parseInt(qrUriMatcher.group("counter")) : null;
RealmRepresentation realmRep = testRealmResource().toRepresentation();
String expectedRealmName = realmRep.getDisplayName() != null && !realmRep.getDisplayName().isEmpty() ? realmRep.getDisplayName() : realmRep.getRealm();
// basic assertations
assertEquals(QR_CODE, qrCode.getBarcodeFormat());
assertEquals(expectedRealmName, realm);
assertEquals(expectedRealmName, issuer);
assertEquals(testUser.getUsername(), user);
// the actual test
testOtp(type, algorithm, digits, period, counter, secret);
}
use of org.openqa.selenium.htmlunit.HtmlUnitDriver in project keycloak by keycloak.
the class AbstractFirstBrokerLoginTest method testLinkAccountByLogInAsUserUsingBrowserButtons.
/**
* Refers to in old test suite: org.keycloak.testsuite.broker.AbstractFirstBrokerLoginTest#testLinkAccountByReauthenticationWithPassword_browserButtons
*/
@Test
public void testLinkAccountByLogInAsUserUsingBrowserButtons() {
updateExecutions(AbstractBrokerTest::disableUpdateProfileOnFirstLogin);
String userId = createUser("consumer");
UserResource providerUser = adminClient.realm(bc.providerRealmName()).users().get(this.userId);
UserRepresentation userResource = providerUser.toRepresentation();
userResource.setEmail(USER_EMAIL);
userResource.setFirstName("FirstName");
userResource.setLastName("LastName");
providerUser.update(userResource);
driver.navigate().to(getAccountUrl(getConsumerRoot(), bc.consumerRealmName()));
log.debug("Clicking social " + bc.getIDPAlias());
loginPage.clickSocial(bc.getIDPAlias());
waitForPage(driver, "sign in to", true);
Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/"));
log.debug("Logging in");
// we need to force a login failure in order to be able to use back button to go back to login page at the provider
loginPage.login("invalid", bc.getUserPassword());
loginPage.login(bc.getUserLogin(), bc.getUserPassword());
waitForPage(driver, "account already exists", false);
// Click browser 'back' and then 'forward' and then continue
driver.navigate().back();
assertTrue(driver.getPageSource().contains("You are already logged in."));
// here a new execution ID is added to the URL using JS, see below
driver.navigate().forward();
idpConfirmLinkPage.assertCurrent();
// Click browser 'back' on review profile page
idpConfirmLinkPage.clickReviewProfile();
waitForPage(driver, "update account information", false);
updateAccountInformationPage.assertCurrent();
driver.navigate().back();
// JS-capable browsers (i.e. all except HtmlUnit) add a new execution ID to the URL which then causes the login expire page to appear (because the old ID and new ID don't match)
if (!(driver instanceof HtmlUnitDriver)) {
loginExpiredPage.assertCurrent();
loginExpiredPage.clickLoginContinueLink();
}
waitForPage(driver, "update account information", false);
updateAccountInformationPage.assertCurrent();
updateAccountInformationPage.updateAccountInformation(bc.getUserEmail(), "FirstName", "LastName");
waitForPage(driver, "account already exists", false);
idpConfirmLinkPage.assertCurrent();
idpConfirmLinkPage.clickLinkAccount();
// Login screen shown. Username is prefilled. Registration link and social buttons are not shown
assertEquals("consumer", loginPage.getUsername());
assertTrue(loginPage.isUsernameInputEnabled());
assertEquals("Authenticate to link your account with " + bc.getIDPAlias(), this.loginPage.getInfoMessage());
try {
loginPage.findSocialButton(bc.getIDPAlias());
Assert.fail("Not expected to see social button with " + bc.getIDPAlias());
} catch (NoSuchElementException expected) {
}
// Use correct password now
loginPage.login("password");
waitForAccountManagementTitle();
accountUpdateProfilePage.assertCurrent();
assertNumFederatedIdentities(userId, 1);
}
use of org.openqa.selenium.htmlunit.HtmlUnitDriver in project keycloak by keycloak.
the class WaitUtils method waitForDomContentToLoad.
/**
* Waits for DOMContent to load
*/
public static void waitForDomContentToLoad() {
WebDriver driver = getCurrentDriver();
if (driver instanceof HtmlUnitDriver) {
// not needed
return;
}
WebDriverWait wait = new WebDriverWait(driver, PAGELOAD_TIMEOUT_MILLIS / 1000);
try {
wait.pollingEvery(Duration.ofMillis(500)).until(javaScriptThrowsNoExceptions("if (document.readyState !== 'complete') { throw \"Not ready\";}"));
} catch (TimeoutException e) {
log.warn("waitForPageToLoad time exceeded!");
}
}
use of org.openqa.selenium.htmlunit.HtmlUnitDriver in project keycloak by keycloak.
the class WaitUtils method waitForPageToLoad.
/**
* Waits for page to finish any pending redirects, REST API requests etc.
* Because Keycloak's Admin Console is a single-page application, we need to
* take extra steps to ensure the page is fully loaded
*/
public static void waitForPageToLoad() {
WebDriver driver = getCurrentDriver();
if (driver instanceof HtmlUnitDriver) {
// not needed
return;
}
String currentUrl = null;
// Ensure the URL is "stable", i.e. is not changing anymore; if it'd changing, some redirects are probably still in progress
for (int maxRedirects = 4; maxRedirects > 0; maxRedirects--) {
currentUrl = driver.getCurrentUrl();
FluentWait<WebDriver> wait = new FluentWait<>(driver).withTimeout(Duration.ofMillis(250));
try {
wait.until(not(urlToBe(currentUrl)));
} catch (TimeoutException e) {
// URL has not changed recently - ok, the URL is stable and page is current
break;
}
if (maxRedirects == 1) {
log.warn("URL seems unstable! (Some redirect are probably still in progress)");
}
}
WebDriverWait wait = new WebDriverWait(getCurrentDriver(), PAGELOAD_TIMEOUT_MILLIS / 1000);
ExpectedCondition waitCondition = null;
// Different wait strategies for Admin and Account Consoles
if (currentUrl.matches("^[^\\/]+:\\/\\/[^\\/]+\\/auth\\/admin\\/.*$")) {
// Admin Console
// Checks if the document is ready and asks AngularJS, if present, whether there are any REST API requests in progress
waitCondition = javaScriptThrowsNoExceptions("if (document.readyState !== 'complete' " + "|| (typeof angular !== 'undefined' && angular.element(document.body).injector().get('$http').pendingRequests.length !== 0)) {" + "throw \"Not ready\";" + "}");
} else if (// check for new Account Console URL
currentUrl.matches("^[^\\/]+:\\/\\/[^\\/]+\\/auth\\/realms\\/[^\\/]+\\/account\\/.*#/.+$")) {
// TODO rework this temporary workaround once KEYCLOAK-11201 and/or KEYCLOAK-8181 are fixed
pause(2000);
}
if (waitCondition != null) {
try {
wait.until(waitCondition);
} catch (TimeoutException e) {
log.warn("waitForPageToLoad time exceeded!");
}
}
}
Aggregations