com.axonivy.ivy.webtest.engine.WebAppFixture Maven / Gradle / Ivy
Show all versions of web-tester Show documentation
/*
* Copyright (C) 2021 Axon Ivy AG
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.axonivy.ivy.webtest.engine;
import static com.codeborne.selenide.Condition.visible;
import static com.codeborne.selenide.Selenide.$;
import static com.codeborne.selenide.Selenide.open;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse.BodyHandlers;
import java.util.Base64;
import javax.ws.rs.core.UriBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import com.axonivy.ivy.webtest.IvyWebTest;
import com.codeborne.selenide.Selenide;
/**
*
* Use the WebAppFixture to temporary change the active environment for your web tests.
*
Changes are not rollbacked automatically to the previous value after the test.
* To use the AppFixture annotate your test class with the {@link IvyWebTest} annotation.
* Then add the AppFixture as parameter to any {@link Test}, {@link BeforeEach}, {@link AfterEach},
* methods or the constructor of the test class.
* Example:
*
* {@literal @IvyWebTest}
* class Test {
* {@literal @Test}
* void test(WebAppFixture fixture) {
* open(EngineUrl.create().toUrl());
* $(By.id("sessionUserName")).shouldBe(Condition.exactText("Developer"));
* fixture.login("test", "test");
* $(By.id("sessionUserName")).shouldBe(Condition.exactText("test"));
* }
* }
*
* @since 10.0.14
*/
public class WebAppFixture {
private static final String VAR_PATH = "variables";
private static final String CONFIG_PATH = "configs";
/**
* Login to a user.
* This user will be used as long as the browser context isn't closed or the {@link #logout()} method is called.
* It uses the login form of the Dev-Workflow-UI.
* Example:
*
* {@literal @Test}
* void test(WebAppFixture fixture) {
* open(EngineUrl.create().toUrl());
* $(By.id("sessionUserName")).shouldBe(Condition.exactText("Developer"));
* fixture.login("test", "test");
* $(By.id("sessionUserName")).shouldBe(Condition.exactText("test"));
* }
*
* @param username the name of the user
* @param password the password of the user
*/
public void login(String username, String password) {
var currentUrl = Selenide.webdriver().driver().url();
open(EngineUrl.create().app("").path("dev-workflow-ui/faces/login.xhtml").toUrl());
$(By.id("loginForm:userName")).shouldBe(visible).sendKeys(username);
$(By.id("loginForm:password")).shouldBe(visible).sendKeys(password);
$(By.id("loginForm:login")).shouldBe(visible).click();
$(By.id("loginForm:login")).shouldNotBe(visible);
if (!"about:blank".equals(currentUrl)) {
open(currentUrl);
}
}
/**
* Logout the current user.
* This method logout the current user by using the Dev-Workflow-UI.
* Example:
*
* {@literal @Test}
* void test(WebAppFixture fixture) {
* open(EngineUrl.create().toUrl());
* $(By.id("sessionUserName")).shouldBe(Condition.exactText("Developer"));
* fixture.logout();
* $(By.id("sessionUserName")).shouldBe(Condition.exactText("test"));
* }
*
*/
public void logout() {
var currentUrl = Selenide.webdriver().driver().url();
open(EngineUrl.create().app("").path("dev-workflow-ui/faces/home.xhtml").toUrl());
$(By.id("sessionUserName")).shouldBe(visible).click();
$(By.id("sessionLogoutBtn")).shouldBe(visible).click();
open(currentUrl);
}
/**
* Set a variable to a given value.
* This variable will be set as long it is not been {@link #resetVar(String)}.
* Example:
*
* {@literal @Test}
* void test(WebAppFixture fixture) {
* fixture.var("myVar", "myNewValue");
* }
*
*/
public void var(String name, String value) {
try {
var url = configRestUrl().path(VAR_PATH).path(name).build();
sendRequest(HttpRequest.newBuilder(url).POST(BodyPublishers.ofString(value)));
} catch (Exception ex) {
throw new RuntimeException("Couldn't set variable", ex);
}
}
/**
* Reset a variable to the initial value.
* Example:
*
* {@literal @Test}
* void test(WebAppFixture fixture) {
* fixture.var("myVar", "myNewValue");
* //do some tests
* fixture.resetVar("myVar");
* }
*
*/
public void resetVar(String name) {
try {
var url = configRestUrl().path(VAR_PATH).path(name).build();
sendRequest(HttpRequest.newBuilder(url).DELETE());
} catch (Exception ex) {
throw new RuntimeException("Couldn't remove variable", ex);
}
}
/**
* Set an app configuration (like rest or web service,...) to a given value.
* This configuration will be set as long it is not been {@link #resetConfig(String)}.
* Example:
*
* {@literal @Test}
* void test(WebAppFixture fixture) {
* fixture.config("RestClients.MyRestClient.Url", "${ivy.app.baseurl}/api/myCoolMockService");
* }
*
*/
public void config(String name, String value) {
try {
var url = configRestUrl().path(CONFIG_PATH).path(name).build();
sendRequest(HttpRequest.newBuilder(url).POST(BodyPublishers.ofString(value)));
} catch (Exception ex) {
throw new RuntimeException("Couldn't set config", ex);
}
}
/**
* Reset an app configuration (like rest or web service,...) to an initial value.
* Example:
*
* {@literal @Test}
* void test(WebAppFixture fixture) {
* fixture.config("RestClients.MyRestClient.Url", "${ivy.app.baseurl}/api/myCoolMockService");
* //do some tests
* fixture.resetConfig("RestClients.MyRestClient.Url");
* }
*
*/
public void resetConfig(String name) {
try {
var url = configRestUrl().path(CONFIG_PATH).path(name).build();
sendRequest(HttpRequest.newBuilder(url).DELETE());
} catch (Exception ex) {
throw new RuntimeException("Couldn't remove config", ex);
}
}
private static UriBuilder configRestUrl() {
return EngineUrl.create().app("system").rest("apps").builder().path(EngineUrl.applicationName());
}
private void sendRequest(HttpRequest.Builder requestBuilder) throws Exception {
var client = HttpClient.newBuilder().build();
var request = requestBuilder
.header("Authorization", basicAuth("admin", "admin"))
.header("X-Requested-By", "webtest").build();
var response = client.send(request, BodyHandlers.ofString());
if (response.statusCode() > 399) {
throw new RuntimeException("Couldn't send web app fixture request (status code: " + response.statusCode() + "): " + response.body());
}
}
private static final String basicAuth(String username, String password) {
var value = username + ":" + password;
return "Basic " + Base64.getEncoder().encodeToString(value.getBytes());
}
}