Я уже реализовал сетевой перехват используя пакет DevTools, но он привязан к конкретной версии и работает только в браузерах Chromium. Чтобы добиться той же функциональности и большей гибкости, я хочу использовать API BiDi. На данный момент у меня есть вот что:
Класс для управления сетевым перехватом и доступа к ответам на запросы.
Код: Выделить всё
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v125.network.Network;
import org.openqa.selenium.devtools.v125.network.model.Request;
import org.openqa.selenium.devtools.v125.network.model.RequestId;
import org.openqa.selenium.devtools.v125.network.model.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class NetworkInterceptor {
@Autowired
private DevTools devTools;
private final CountDownLatch latch;
private RequestId interceptedRequestId;
@Autowired
public NetworkInterceptor() {
this.latch = new CountDownLatch(1);
}
/**
* Intercepts a request with a specific URL and method, so that the test can wait for it to complete.
* Be aware that you must call {@link NetworkInterceptor#waitForResponse()} after the request is triggered.
* @param urlRegex The regex to match the URL of the request to intercept. For example: ".*articles/" + variable*/
public void interceptResponse(String urlRegex, String requestMethod) {
final ConcurrentHashMap requestMap = new ConcurrentHashMap();
devTools.addListener(Network.requestWillBeSent(), request -> requestMap.put(request.getRequestId().toString(), request.getRequest()));
devTools.addListener(Network.responseReceived(), response -> {
Response res = response.getResponse();
if (res.getUrl().matches(urlRegex) && requestMap.containsKey(response.getRequestId().toString())) {
Request interceptedRequest = requestMap.get(response.getRequestId().toString());
if (interceptedRequest.getMethod().equals(requestMethod)) {
this.interceptedRequestId = response.getRequestId();
System.out.println("Intercepted response: " + res.getUrl() + " with status " + res.getStatus());
markRequestAsCompleted();
}
}
});
}
/**
* Waits for the intercepted request to complete and returns the response body.
* @return The response body of the intercepted request
*/
public String waitForResponse() {
try {
boolean completed = latch.await(10, TimeUnit.SECONDS);
if (!completed) {
throw new RuntimeException("The specific request did not complete within the timeout period");
}
return getResponseBody();
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while waiting for request to complete", e);
}
}
private String getResponseBody() {
Network.GetResponseBodyResponse bodyResponse = devTools.send(Network.getResponseBody(interceptedRequestId));
return bodyResponse.getBody();
}
private void markRequestAsCompleted() {
latch.countDown();
}
}
Вот пример теста, демонстрирующий использование этих методов:
Код: Выделить всё
public void followAuthor() {
// Arrange
authorApi.unfollowAuthor(0);
var authorName = authorDetailPage.visit(0);
// Act
networkInterceptor.interceptResponse(".*/profiles/" + authorName + "/follow", "POST");
followAuthorButton.clickButton();
boolean isFollowing = JsonPath.parse(networkInterceptor.waitForResponse()).read("$.profile.following");
// Assert
assertThat(followAuthorButton.getButton().getText()).contains("Unfollow");
assertThat(isFollowing).isTrue();
}
[*]Перехватить запрос, предоставляющий регулярное выражение URL-адреса и метод запроса, просто используя простой метод< /li>
Выполните какое-либо действие, которое инициирует запрос.
[*]Подождите, пока запрос завершится, и получите доступ к телу его ответа.
< /ul>
Прокси-сервер BrowserMob не подходит, так как я читал, что он больше не поддерживается с 2016 года.
Подробнее здесь: https://stackoverflow.com/questions/786 ... enium-bidi