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:
Nanne Baars
2025-01-26 16:59:59 +01:00
committed by GitHub
parent 9d5ab5fb21
commit 8e45316638
47 changed files with 599 additions and 281 deletions

View File

@ -0,0 +1,170 @@
package org.owasp.webgoat.integration;
import static org.junit.jupiter.api.Assertions.assertTrue;
import io.restassured.RestAssured;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
public class ChallengeIntegrationTest extends IntegrationTest {
@Test
void testChallenge1() {
startLesson("Challenge1");
byte[] resultBytes =
RestAssured.given()
.when()
.relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie())
.get(url("challenge/logo"))
.then()
.statusCode(200)
.extract()
.asByteArray();
String pincode = new String(Arrays.copyOfRange(resultBytes, 81216, 81220));
Map<String, Object> params = new HashMap<>();
params.clear();
params.put("username", "admin");
params.put("password", "!!webgoat_admin_1234!!".replace("1234", pincode));
checkAssignment(url("challenge/1"), params, true);
String result =
RestAssured.given()
.when()
.relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie())
.formParams(params)
.post(url("challenge/1"))
.then()
.statusCode(200)
.extract()
.asString();
String flag = result.substring(result.indexOf("flag") + 6, result.indexOf("flag") + 42);
params.clear();
params.put("flag", flag);
checkAssignment(url("challenge/flag/1"), params, true);
checkResults("Challenge1");
List<String> capturefFlags =
RestAssured.given()
.when()
.relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie())
.get(url("scoreboard-data"))
.then()
.statusCode(200)
.extract()
.jsonPath()
.get("find { it.username == \"" + this.getUser() + "\" }.flagsCaptured");
assertTrue(capturefFlags.contains("Admin lost password"));
}
@Test
void testChallenge5() {
startLesson("Challenge5");
Map<String, Object> params = new HashMap<>();
params.clear();
params.put("username_login", "Larry");
params.put("password_login", "1' or '1'='1");
String result =
RestAssured.given()
.when()
.relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie())
.formParams(params)
.post(url("challenge/5"))
.then()
.statusCode(200)
.extract()
.asString();
String flag = result.substring(result.indexOf("flag") + 6, result.indexOf("flag") + 42);
params.clear();
params.put("flag", flag);
checkAssignment(url("challenge/flag/5"), params, true);
checkResults("Challenge5");
List<String> capturefFlags =
RestAssured.given()
.when()
.relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie())
.get(url("scoreboard-data"))
.then()
.statusCode(200)
.extract()
.jsonPath()
.get("find { it.username == \"" + this.getUser() + "\" }.flagsCaptured");
assertTrue(capturefFlags.contains("Without password"));
}
@Test
void testChallenge7() {
startLesson("Challenge7");
cleanMailbox();
// One should first be able to download git.zip from WebGoat
RestAssured.given()
.when()
.relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie())
.get(url("challenge/7/.git"))
.then()
.statusCode(200)
.extract()
.asString();
// Should email WebWolf inbox this should give a hint to the link being static
RestAssured.given()
.when()
.relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie())
.formParams("email", getUser() + "@webgoat.org")
.post(url("challenge/7"))
.then()
.statusCode(200)
.extract()
.asString();
// Check whether email has been received
var responseBody =
RestAssured.given()
.when()
.relaxedHTTPSValidation()
.cookie("WEBWOLFSESSION", getWebWolfCookie())
.get(new WebWolfUrlBuilder().path("mail").build())
.then()
.extract()
.response()
.getBody()
.asString();
Assertions.assertThat(responseBody).contains("Hi, you requested a password reset link");
// Call reset link with admin link
String result =
RestAssured.given()
.when()
.relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie())
.get(url("challenge/7/reset-password/{link}"), "375afe1104f4a487a73823c50a9292a2")
.then()
.statusCode(HttpStatus.ACCEPTED.value())
.extract()
.asString();
String flag = result.substring(result.indexOf("flag") + 6, result.indexOf("flag") + 42);
checkAssignment(url("challenge/flag/7"), Map.of("flag", flag), true);
}
}