Перехват сети и доступ к ответу на запрос с помощью Selenium BiDiJAVA

Программисты JAVA общаются здесь
Anonymous
Перехват сети и доступ к ответу на запрос с помощью Selenium BiDi

Сообщение Anonymous »

В настоящее время я работаю над этим демонстрационным проектом с использованием Selenium Java, чтобы изучить функциональные возможности, которые я обычно использую в проектах автоматизации тестирования e2e, и использовать его в качестве справочного материала для будущих проектов. Я хотел бы знать, есть ли способ перехватить сетевые запросы и получить доступ к их телу ответа с помощью API Selenium BiDi.
Я уже реализовал сетевой перехват используя пакет 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
* @param requestMethod The method of the request to intercept
*/
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();
}
Я видел похожее решение на Stack Overflow, но оно включало слишком подробный код внутри самих тестов. Кроме того, я не смог найти способ получить доступ к телу ответа. В идеале я хотел бы добиться функциональности, продемонстрированной в тесте:

[*]Перехватить запрос, предоставляющий регулярное выражение URL-адреса и метод запроса, просто используя простой метод< /li>
Выполните какое-либо действие, которое инициирует запрос.
[*]Подождите, пока запрос завершится, и получите доступ к телу его ответа.
< /ul>
Прокси-сервер BrowserMob не подходит, так как я читал, что он больше не поддерживается с 2016 года.

Подробнее здесь: https://stackoverflow.com/questions/786 ... enium-bidi

Вернуться в «JAVA»