0

I need to perform validation that specific String is appearing in DevTools traffic (Selenium 4 / Java)
I saw several examples like this:

devTools.addListener(Network.responseReceived(), entry -> {
    System.out.println("Response (Req id) URL : (" + entry.getRequestId() + ") "
            + entry.getResponse().getUrl()
            + " (" + entry.getResponse().getStatus() + ")");
});

The code above works correctly, it prints out the traffic response value.
But I need not just to print the values but to perform validation if some specific String is contained in one of the entries response URL.
I tried something like this:

boolean responseFound = false;

devTools.addListener(Network.responseReceived(), entry -> {            
            if (entry.getResponse().getUrl().contains(expectedUrl)){
                responseFound = true;
            }            
});

However Java considered this as illegal since

Variable used in lambda expression should be final or effectively final

So I changed it to be

AtomicBoolean responseFound = new AtomicBoolean(false);

devTools.addListener(Network.responseReceived(), entry -> {
            if (entry.getResponse().getUrl().contains(expectedUrl)){
               responseFound.set(true);
           }
});

However the code above doesn't work.
While debugging I see the flow never performs the if statement, it directly goes to the next line....
How can I make it working correctly?

1 Answer 1

1

The listener is likely receiving events on another thread. I'm guessing you want to block the main thread whilst waiting for the response event. There's a few ways to do this, here's an example with a CountDownLatch

CountDownLatch latch = new CountDownLatch(1);
List<Response> responses = new CopyOnWriteArrayList<>();
AtomicBoolean urlFound = new AtomicBoolean(false);

devTools.addListener(Network.responseReceived(), entry -> {
   responses.add(entry.getResponse());
   if (response.getUrl().contains(expectedUrl)) {
      urlFound.set(true);
      latch.countDown(); // decrement the count
   }
});

latch.await(10, TimeUnit.SECONDS); // waits until count is zero for max of 10 seconds

if (urlFound.get()) {
   // yay we found it
} else {
   for (Response response : responses) {
      // report errors
   }
}
15
  • Thank you very much for your answer. I followed after your code versions and really appreciate your efforts. However the current code catches only single, probably the first Response while network contains several Responses with different URLs while the required Response seems to be not the first. I can't know how many Responses will be caught here.
    – Prophet
    Commented Sep 21, 2023 at 13:11
  • Also, I think the delay is not the problem. I can set some pause of 2-3 seconds or so. The main issue is to catch all the Responses and then iterate over them and validate their content.
    – Prophet
    Commented Sep 21, 2023 at 13:13
  • In the listener you could check each event to find the one you are interested in. And only set the reference & countdown the latch once you've found the response you want
    – lance-java
    Commented Sep 21, 2023 at 13:16
  • If you just want to wait 3 seconds and check all responses you could use AtomicReference<List<Response>> and Thread.sleep(...) instead of a latch. Make sure to use a thread safe list (eg CopyOnWriteArrayList)
    – lance-java
    Commented Sep 21, 2023 at 13:18
  • But I don't know how many responses are there. Also it can be that the required String is not there. So, I think we just need to put all the responses in some external List / Map etc and then to perform validation via the iterations. The original code that only prints the content works just perfect with no need for any kind of CountDownLatch
    – Prophet
    Commented Sep 21, 2023 at 13:20

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.