In UI tests, there's often a need to authenticate users. Instead of the slow and unstable process of entering login/password through the web interface, you can use API to get a token and set it in the browser via JavaScript. This significantly speeds up and stabilizes tests.
In BaseUiTest you need to create a static method that opens the browser, gets a token via API (which is significantly faster than through UI) and adds it to the browser's localStorage:
public static void authAsUser(String username, String password) {
Selenide.open("/");
String userAuthToken = RequestSpecs.getUserAuthHeader(username, password);
executeJavaScript("localStorage.setItem('authToken', arguments[0]);", userAuthToken);
}
The getUserAuthHeader method from RequestSpecs class performs API login and returns a token (if the token is already in storage, it doesn't even make a request):
public static String getUserAuthHeader(String username, String password) {
String userAuthToken;
if (!authHeaders.containsKey(username)) {
userAuthToken = new CrudRequester(RequestSpecs.unauthSpec(),
ResponseSpecs.responseReturns200Spec(),
Endpoint.AUTH_LOGIN)
.post(LoginUserRequestModel.builder().username(username).password(password).build())
.extract()
.header("Authorization");
authHeaders.put(username, userAuthToken);
} else {
userAuthToken = authHeaders.get(username);
}
return userAuthToken;
}
Accordingly, in the test itself we first create a user and login using it:
@Test
void userCanCreateAccount() {
CreateUserRequestModel user = AdminSteps.createUser(); // create user
authAsUser(user.getUsername(), user.getPassword()); // login
// then test steps follow
}