import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v154.network.Network;
import org.openqa.selenium.devtools.v154.network.model.RequestId;
public class NetworkLogCapture {
public static Logger APP_LOGS = LogManager.getLogger(NetworkLogCapture.class.getName());
private DevTools devTools;
private final List<String> failedRequests = new ArrayList<>();
public void enableNetworkLogging(ChromeDriver driver) {
devTools = driver.getDevTools();
devTools.createSession();
// Store URL per requestId for correlation
Map<String, String> requestUrlMap = new ConcurrentHashMap<>();
// Enable Network domain
devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(),
Optional.empty()));
// Log all requests
devTools.addListener(Network.requestWillBeSent(), request -> {
String url = request.getRequest().getUrl();
requestUrlMap.put(request.getRequestId().toString(), url);
APP_LOGS.info("\n=== REQUEST ===");
APP_LOGS.info("URL : " + url);
APP_LOGS.info("Method : " + request.getRequest().getMethod());
APP_LOGS.info("Headers : " + request.getRequest().getHeaders());
// Request body (only for POST/PUT)
request.getRequest().getPostDataEntries().ifPresent(b -> APP_LOGS.info("REQUEST BODY : " + b));
// Fetch post data via CDP if not inline
try {
RequestId requestId = request.getRequestId();
String postData = devTools.send(Network.getRequestPostData(requestId)).getPostData();
APP_LOGS.info("[REQUEST BODY - CDP] " + postData);
} catch (Exception e) {
APP_LOGS.info("[REQUEST BODY] Not available: " + e.getMessage());
}
});
// Log all responses
devTools.addListener(Network.responseReceived(), response -> {
int status = response.getResponse().getStatus();
String url = response.getResponse().getUrl();
// Flag non-2xx responses (blocked, failed, etc.)
if (status >= 400 || status == 0) {
failedRequests.add(status + " | " + url);
APP_LOGS.info("\n=== RESPONSE HEADERS ===");
APP_LOGS.info("Status : " + status);
APP_LOGS.info("URL : " + url);
APP_LOGS.info("Headers : " + response.getResponse().getHeaders());
}
});
// Log load failures (blocked by firewall/CSP)
devTools.addListener(Network.loadingFinished(), finished -> {
String url = requestUrlMap.getOrDefault(finished.getRequestId().toString(), "");
try {
Network.GetResponseBodyResponse body = devTools.send(Network.getResponseBody(finished.getRequestId()));
APP_LOGS.info("\n=== RESPONSE BODY (" + url + ") ===");
APP_LOGS.info(body.getBase64Encoded() ? new String(java.util.Base64.getDecoder().decode(body.getBody()))
: body.getBody());
} catch (Exception e) {
APP_LOGS.info("[RESPONSE BODY] Skipped: " + e.getMessage());
}
});
// Log load failures (blocked by firewall/CSP)
devTools.addListener(Network.loadingFailed(), failed -> {
APP_LOGS.error("[FAILED] " + failed.getErrorText() + " | blocked=" + failed.getBlockedReason()
+ " | url type=" + failed.getType());
});
}
public void printFailedRequests() {
APP_LOGS.info("=== FAILED/BLOCKED REQUESTS ===");
failedRequests.forEach(msg -> APP_LOGS.error(msg));
}
}
Tuesday, October 6, 2026
Network Log Capture
Friday, April 10, 2026
Appium Automating Mobile Gestures
Android gesture: There is a couple of basic gestures, like swipe, fling or pinch, which are commonly used in Android applications
public void swipeUp() {
Dimension size = driver.manage().window().getSize();
int startX = size.getWidth() / 2;
int startY = (int) (size.getHeight() * 0.8);
int endY = (int) (size.getHeight() * 0.2);
performSwipe(startX, startY, startX, endY);
}
public void swipeDown() {
Dimension size = driver.manage().window().getSize();
int startX = size.getWidth() / 2;
int startY = (int) (size.getHeight() * 0.2);
int endY = (int) (size.getHeight() * 0.8);
performSwipe(startX, startY, startX, endY);
}
public void swipeLeft() {
Dimension size = driver.manage().window().getSize();
int startX = (int) (size.getWidth() * 0.8);
int endX = (int) (size.getWidth() * 0.2);
int y = size.getHeight() / 2;
performSwipe(startX, y, endX, y);
}
public void swipeRight() {
Dimension size = driver.manage().window().getSize();
int startX = (int) (size.getWidth() * 0.2);
int endX = (int) (size.getWidth() * 0.8);
int y = size.getHeight() / 2;
performSwipe(startX, y, endX, y);
}
public void longPress(WebElement element) {
Point center = getCenter(element);
PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
Sequence longPressSeq = new Sequence(finger, 0);
longPressSeq.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), center.getX(), center.getY()));
longPressSeq.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()));
longPressSeq.addAction(new Pause(finger, Duration.ofSeconds(2)));
longPressSeq.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));
driver.perform(Collections.singletonList(longPressSeq));
}
public void doubleTap(WebElement element) {
Point center = getCenter(element);
PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
Sequence doubleTapSeq = new Sequence(finger, 0);
doubleTapSeq.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), center.getX(), center.getY()));
doubleTapSeq.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()));
doubleTapSeq.addAction(new Pause(finger, Duration.ofMillis(50)));
doubleTapSeq.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));
doubleTapSeq.addAction(new Pause(finger, Duration.ofMillis(100)));
doubleTapSeq.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()));
doubleTapSeq.addAction(new Pause(finger, Duration.ofMillis(50)));
doubleTapSeq.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));
driver.perform(Collections.singletonList(doubleTapSeq));
}
private void performSwipe(int startX, int startY, int endX, int endY) {
PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
Sequence swipe = new Sequence(finger, 0);
swipe.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), startX, startY));
swipe.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()));
swipe.addAction(finger.createPointerMove(Duration.ofMillis(600), PointerInput.Origin.viewport(), endX, endY));
swipe.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));
driver.perform(Collections.singletonList(swipe));
}
private Point getCenter(WebElement element) {
Point loc = element.getLocation();
Dimension size = element.getSize();
return new Point(loc.getX() + size.getWidth() / 2, loc.getY() + size.getHeight() / 2);
}
How to capture browser network logs
Create a Chrome devtool object
protected static DevTools devTools;
Call below function in the setup method.
/**
* To capture browser network logs
*/
public void getBrowserNetworkLogs() {
if (getBrowserName().equalsIgnoreCase("CHROME")) {
// Create a session with DevTools
devTools = ((ChromeDriver) driver).getDevTools();
devTools.createSession();
devTools.send(Network.clearBrowserCache());
devTools.send(Network.setCacheDisabled(true));
// Enable network tracking
devTools.send(Network.enable(java.util.Optional.empty(), java.util.Optional.empty(),
java.util.Optional.empty(), java.util.Optional.empty(), java.util.Optional.empty()));
// final RequestId[] requestIds = new RequestId[1];
// Capturing request information of a network call
/*
* devTools.addListener(Network.requestWillBeSent(), request -> {
* APP_LOGS.error("Request: " + request.getRequest().getUrl()); });
*/
// Capturing response information of a network call
devTools.addListener(Network.responseReceived(), response -> {
RequestId requestId = response.getRequestId();
if (response.getResponse().getStatus() != 200) {
String responseUrl = response.getResponse().getUrl();
if (responseUrl.contains("chubb") && !responseUrl.contains("favicon.ico")
&& !responseUrl.contains("chubb-publico")) {
int responsStatus = response.getResponse().getStatus();
// String responseType = response.getType().toJson();
String statusText = response.getResponse().getStatusText();
String responseHeaders = response.getResponse().getRequestHeaders() != null
? response.getResponse().getRequestHeaders().toString()
: "N/A";
String responseBody = devTools.send(Network.getResponseBody(requestId)).getBody();
String requestPostData = devTools.send(Network.getRequestPostData(requestId)).toString();
APP_LOGS.error("Response Url: " + responseUrl);
APP_LOGS.error("Response Status Code: " + responsStatus);
APP_LOGS.error("Response Text: " + statusText);
APP_LOGS.error("Response Headers: " + responseHeaders);
APP_LOGS.error("Response Body: " + responseBody);
APP_LOGS.error("Request Post Data: " + requestPostData);
}
}
});
} else {
APP_LOGS.info("Browser network log not captured for: " + getBrowserName());
}
}
Close the dvetools connection in the tearDown methid.
if (devTools != null) {
devTools.send(Network.disable());
}