Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.test.aad.selenium.login;
package com.azure.test.aad.login;
Comment thread
jacko9et marked this conversation as resolved.
Outdated

import com.azure.test.aad.selenium.SeleniumTestUtils;
import com.azure.test.utils.AppRunner;
import com.azure.test.aad.selenium.AADLoginRunner;
import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.By;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.SpringBootApplication;
Expand All @@ -18,30 +18,35 @@
import org.springframework.web.bind.annotation.RestController;

import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated;

public class AADLoginIT {

private static final Logger LOGGER = LoggerFactory.getLogger(AADLoginIT.class);

@Test
public void loginTest() {
AADLoginRunner.build(DumbApp.class).login().run((app, driver, wait) -> {
AADLoginRunner.EasyTester tester = new AADLoginRunner.EasyTester(app, driver);
tester.assertEquals("api/home", "home");
tester.assertEquals("api/group1", "group1");
tester.assertNotEquals("api/status403", "error");
});
}

try (AppRunner app = new AppRunner(DumbApp.class)) {
SeleniumTestUtils.addProperty(app);
List<String> endPoints = new ArrayList<>();
endPoints.add("api/home");
endPoints.add("api/group1");
endPoints.add("api/status403");
Map<String, String> result = SeleniumTestUtils.get(app, endPoints);
Assert.assertEquals("home", result.get("api/home"));
Assert.assertEquals("group1", result.get("api/group1"));
Assert.assertNotEquals("error", result.get("api/status403"));
}


@Test
public void logoutTest() {
AADLoginRunner.build(DumbApp.class).login().run((app, driver, wait) -> {
driver.get(app.root() + "logout");
wait.until(presenceOfElementLocated(By.cssSelector("button[type='submit']"))).click();
Thread.sleep(10000);
String cssSelector = "div[data-test-id='" + AADLoginRunner.DEFAULT_USERNAME + "']";
driver.findElement(By.cssSelector(cssSelector)).click();
Thread.sleep(10000);
String id = driver.findElement(By.cssSelector("div[tabindex='0']")).getAttribute("data-test-id");
Assert.assertEquals(AADLoginRunner.DEFAULT_USERNAME, id);
});
}

@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
package com.azure.test.aad.selenium;

import com.azure.test.utils.AppRunner;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.regex.Pattern;

import static com.azure.test.aad.AADTestUtils.AAD_MULTI_TENANT_CLIENT_ID;
import static com.azure.test.aad.AADTestUtils.AAD_MULTI_TENANT_CLIENT_SECRET;
import static com.azure.test.aad.AADTestUtils.AAD_TENANT_ID_1;
import static com.azure.test.aad.AADTestUtils.AAD_USER_NAME_1;
import static com.azure.test.aad.AADTestUtils.AAD_USER_PASSWORD_1;
import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated;

public class AADLoginRunner {

public static final String DEFAULT_USERNAME = System.getenv(AAD_USER_NAME_1);
private static final String DEFAULT_PASSWORD = System.getenv(AAD_USER_PASSWORD_1);

private static final Logger LOGGER = LoggerFactory.getLogger(AADLoginRunner.class);

static {
final String directory = "src/test/resources/driver/";
final String chromedriverLinux = "chromedriver_linux64";
final String chromedriverWin32 = "chromedriver_win32.exe";
final String chromedriverMac = "chromedriver_mac64";
String osName = System.getProperty("os.name").toLowerCase();
Process process = null;
try {
File dir = new File(directory);
if (Pattern.matches("linux.*", osName)) {
process = Runtime.getRuntime().exec("chmod +x " + chromedriverLinux, null, dir);
process.waitFor();
System.setProperty(ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY, directory + chromedriverLinux);
} else if (Pattern.matches("windows.*", osName)) {
System.setProperty(ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY, directory + chromedriverWin32);
} else if (Pattern.matches("mac.*", osName)) {
process = Runtime.getRuntime().exec("chmod +x " + chromedriverMac, null, dir);
process.waitFor();
System.setProperty(ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY, directory + chromedriverMac);
} else {
throw new IllegalStateException("Can not recognize osName. osName = " + System.getProperty("os"
+ ".name"));
}
} catch (InterruptedException | IOException e) {
throw new RuntimeException(e);
} finally {
if (process != null) {
process.destroy();
}
}
}

private final AppRunner app;
private final WebDriver driver;
private final String password;
private final String username;
private final WebDriverWait wait;

private AADLoginRunner(String username, String password, AppRunner app, WebDriver driver) {
this.username = username;
this.password = password;
this.app = app;
this.driver = driver;
this.wait = new WebDriverWait(this.driver, 10);
}

public static AADLoginRunnerConfiguration build(Class<?> appClass) {
return new AADLoginRunnerConfiguration(appClass);
}

public void run(BrowserCommandWithAppRunner command) {
try {
this.app.start();
command.login(login())
.andThen((app, driver, wait) -> LOGGER.info("Test ===> {}.{}() has finished running.",
Thread.currentThread().getStackTrace()[6].getClassName(),
Thread.currentThread().getStackTrace()[6].getMethodName()))
Comment thread
jacko9et marked this conversation as resolved.
Outdated
.run(this.app, this.driver, this.wait);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (this.driver != null) {
this.driver.quit();
}
if (this.app != null) {
this.app.close();
}
}
}

private BrowserCommandWithAppRunner login() {
return (app, driver, wait) -> {
driver.get(app.root() + "oauth2/authorization/azure");
wait.until(presenceOfElementLocated(By.name("loginfmt")))
.sendKeys(this.username + Keys.ENTER);
Thread.sleep(10000);

driver.findElement(By.name("passwd"))
.sendKeys(this.password + Keys.ENTER);
Thread.sleep(10000);

driver.findElement(By.cssSelector("input[type='submit']")).click();
Thread.sleep(10000);
};
}

@FunctionalInterface
public interface BrowserCommandWithAppRunner {

default BrowserCommandWithAppRunner andThen(BrowserCommandWithAppRunner after) {
Objects.requireNonNull(after);
return (AppRunner app, WebDriver driver, WebDriverWait wait) -> {
run(app, driver, wait);
after.run(app, driver, wait);
};
}

default BrowserCommandWithAppRunner login(BrowserCommandWithAppRunner login) {
Objects.requireNonNull(login);
return (AppRunner app, WebDriver driver, WebDriverWait wait) -> {
login.run(app, driver, wait);
run(app, driver, wait);
};
}

void run(AppRunner app, WebDriver driver, WebDriverWait wait) throws Exception;
}

public static class AADLoginRunnerConfiguration {
private final AppRunner app;
private final WebDriver driver;
private Consumer<AppRunner> configure;

private AADLoginRunnerConfiguration(Class<?> appClass) {
this.configure = defautlConfigure();

ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
options.addArguments("--incognito", "--no-sandbox", "--disable-dev-shm-usage");
this.driver = new ChromeDriver(options);

this.app = new AppRunner(appClass);
}

public AADLoginRunnerConfiguration configure(Consumer<AppRunner> configure) {
Comment thread
jacko9et marked this conversation as resolved.
this.configure = configure;
return this;
}

public AADLoginRunner login(String username, String password) {
this.configure.accept(this.app);
Comment thread
jacko9et marked this conversation as resolved.
return new AADLoginRunner(username, password, this.app, this.driver);
}

public AADLoginRunner login() {
return login(DEFAULT_USERNAME, DEFAULT_PASSWORD);
}

private static Consumer<AppRunner> defautlConfigure() {
return app -> {
app.property("azure.activedirectory.tenant-id", System.getenv(AAD_TENANT_ID_1));
app.property("azure.activedirectory.client-id", System.getenv(AAD_MULTI_TENANT_CLIENT_ID));
app.property("azure.activedirectory.client-secret", System.getenv(AAD_MULTI_TENANT_CLIENT_SECRET));
app.property("azure.activedirectory.user-group.allowed-groups", "group1");
app.property("azure.activedirectory.post-logout-redirect-uri", "http://localhost:${server.port}");
};
}
}

public static class EasyTester {
private final AppRunner app;
private final WebDriver driver;

public EasyTester(AppRunner app, WebDriver driver) {
this.app = app;
this.driver = driver;
}

public void assertEquals(String uri, String expected) throws InterruptedException {
Assert.assertEquals(expected, get(uri));
}

public void assertNotEquals(String uri, String expected) throws InterruptedException {
Assert.assertNotEquals(expected, get(uri));
}

private String get(String uri) throws InterruptedException {
this.driver.get(this.app.root() + uri);
Thread.sleep(1000);
return this.driver.findElement(By.tagName("body")).getText();
}
}
}