feat: Introduce Playwright for UI testing
Instead of using Robot Framework which does not run during a `mvn install`. Playwright seems to be the better approach. We can now write them as normal JUnit test and they are executed during a build. Additionally this PR solves some interesting bugs found during writing Playwright tests: - A reset of a lesson removes all assignments as a result another user wouldn't see any assignments - If someone solves an assignment the assignment automatically got solved for a new user since the assignment included the `solved` flag which immediately got copied to new lesson progress. - Introduction of assignment progress linking a assignment not directly to all users.
This commit is contained in:
@ -0,0 +1,229 @@
|
||||
package org.owasp.webgoat.integration;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import io.restassured.path.json.JsonPath;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class LabelAndHintIntegrationTest extends IntegrationTest {
|
||||
|
||||
static final String ESCAPE_JSON_PATH_CHAR = "\'";
|
||||
|
||||
@Test
|
||||
public void testSingleLabel() {
|
||||
Assertions.assertTrue(true);
|
||||
JsonPath jsonPath =
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.relaxedHTTPSValidation()
|
||||
.contentType(ContentType.JSON)
|
||||
.header("Accept-Language", "en")
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.get(url("service/labels.mvc"))
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.jsonPath();
|
||||
|
||||
Assertions.assertEquals(
|
||||
"Try again: but this time enter a value before hitting go.",
|
||||
jsonPath.getString(ESCAPE_JSON_PATH_CHAR + "http-basics.close" + ESCAPE_JSON_PATH_CHAR));
|
||||
|
||||
// check if lang parameter overrules Accept-Language parameter
|
||||
jsonPath =
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.relaxedHTTPSValidation()
|
||||
.contentType(ContentType.JSON)
|
||||
.header("Accept-Language", "en")
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.get(url("service/labels.mvc?lang=nl"))
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.jsonPath();
|
||||
Assertions.assertEquals(
|
||||
"Gebruikersnaam",
|
||||
jsonPath.getString(ESCAPE_JSON_PATH_CHAR + "username" + ESCAPE_JSON_PATH_CHAR));
|
||||
|
||||
jsonPath =
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.relaxedHTTPSValidation()
|
||||
.contentType(ContentType.JSON)
|
||||
.header("Accept-Language", "en")
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.get(url("service/labels.mvc?lang=de"))
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.jsonPath();
|
||||
Assertions.assertEquals(
|
||||
"Benutzername",
|
||||
jsonPath.getString(ESCAPE_JSON_PATH_CHAR + "username" + ESCAPE_JSON_PATH_CHAR));
|
||||
|
||||
// check if invalid language returns english
|
||||
jsonPath =
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.relaxedHTTPSValidation()
|
||||
.contentType(ContentType.JSON)
|
||||
.header("Accept-Language", "nl")
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.get(url("service/labels.mvc?lang=xx"))
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.jsonPath();
|
||||
Assertions.assertEquals(
|
||||
"Username", jsonPath.getString(ESCAPE_JSON_PATH_CHAR + "username" + ESCAPE_JSON_PATH_CHAR));
|
||||
|
||||
// check if invalid language returns english
|
||||
jsonPath =
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.relaxedHTTPSValidation()
|
||||
.contentType(ContentType.JSON)
|
||||
.header("Accept-Language", "xx_YY")
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.get(url("service/labels.mvc"))
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.jsonPath();
|
||||
Assertions.assertEquals(
|
||||
"Username", jsonPath.getString(ESCAPE_JSON_PATH_CHAR + "username" + ESCAPE_JSON_PATH_CHAR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHints() {
|
||||
JsonPath jsonPathLabels = getLabels("en");
|
||||
List<String> allLessons =
|
||||
List.of(
|
||||
"HttpBasics",
|
||||
"HttpProxies",
|
||||
"CIA",
|
||||
"InsecureLogin",
|
||||
"Cryptography",
|
||||
"PathTraversal",
|
||||
"XXE",
|
||||
"JWT",
|
||||
"IDOR",
|
||||
"SSRF",
|
||||
"WebWolfIntroduction",
|
||||
"CrossSiteScripting",
|
||||
"CSRF",
|
||||
"HijackSession",
|
||||
"SqlInjection",
|
||||
"SqlInjectionMitigations",
|
||||
"SqlInjectionAdvanced",
|
||||
"Challenge1");
|
||||
for (String lesson : allLessons) {
|
||||
startLesson(lesson);
|
||||
List<String> hintKeys = getHints();
|
||||
for (String key : hintKeys) {
|
||||
String keyValue =
|
||||
jsonPathLabels.getString(ESCAPE_JSON_PATH_CHAR + key + ESCAPE_JSON_PATH_CHAR);
|
||||
// System.out.println("key: " + key + " ,value: " + keyValue);
|
||||
Assertions.assertNotNull(keyValue);
|
||||
Assertions.assertNotEquals(key, keyValue);
|
||||
}
|
||||
}
|
||||
// Assertions.assertEquals("http-basics.hints.http_basics_lesson.1",
|
||||
// ""+jsonPath.getList("hint").get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLabels() {
|
||||
|
||||
JsonPath jsonPathLabels = getLabels("en");
|
||||
Properties propsDefault = getProperties("");
|
||||
for (String key : propsDefault.stringPropertyNames()) {
|
||||
String keyValue =
|
||||
jsonPathLabels.getString(ESCAPE_JSON_PATH_CHAR + key + ESCAPE_JSON_PATH_CHAR);
|
||||
Assertions.assertNotNull(keyValue);
|
||||
}
|
||||
checkLang(propsDefault, "nl");
|
||||
checkLang(propsDefault, "de");
|
||||
checkLang(propsDefault, "fr");
|
||||
}
|
||||
|
||||
private Properties getProperties(String lang) {
|
||||
Properties prop = null;
|
||||
if (lang == null || lang.equals("")) {
|
||||
lang = "";
|
||||
} else {
|
||||
lang = "_" + lang;
|
||||
}
|
||||
try (InputStream input =
|
||||
new FileInputStream("src/main/resources/i18n/messages" + lang + ".properties")) {
|
||||
|
||||
prop = new Properties();
|
||||
// load a properties file
|
||||
prop.load(input);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
|
||||
private void checkLang(Properties propsDefault, String lang) {
|
||||
JsonPath jsonPath = getLabels(lang);
|
||||
Properties propsLang = getProperties(lang);
|
||||
|
||||
for (String key : propsLang.stringPropertyNames()) {
|
||||
if (!propsDefault.containsKey(key)) {
|
||||
System.err.println("key: " + key + " in (" + lang + ") is missing from default properties");
|
||||
Assertions.fail();
|
||||
}
|
||||
if (!jsonPath
|
||||
.getString(ESCAPE_JSON_PATH_CHAR + key + ESCAPE_JSON_PATH_CHAR)
|
||||
.equals(propsLang.get(key))) {
|
||||
System.out.println(
|
||||
"key: " + key + " in (" + lang + ") has incorrect translation in label service");
|
||||
System.out.println(
|
||||
"actual:" + jsonPath.getString(ESCAPE_JSON_PATH_CHAR + key + ESCAPE_JSON_PATH_CHAR));
|
||||
System.out.println("expected: " + propsLang.getProperty(key));
|
||||
System.out.println();
|
||||
Assertions.fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JsonPath getLabels(String lang) {
|
||||
return RestAssured.given()
|
||||
.when()
|
||||
.relaxedHTTPSValidation()
|
||||
.contentType(ContentType.JSON)
|
||||
.header("Accept-Language", lang)
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
// .log().headers()
|
||||
.get(url("service/labels.mvc"))
|
||||
.then()
|
||||
// .log().all()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.jsonPath();
|
||||
}
|
||||
|
||||
private List<String> getHints() {
|
||||
JsonPath jsonPath =
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.relaxedHTTPSValidation()
|
||||
.contentType(ContentType.JSON)
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.get(url("service/hint.mvc"))
|
||||
.then()
|
||||
// .log().all()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.jsonPath();
|
||||
return jsonPath.getList("hint");
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user