javalambdaiterationgoogle-chrome-devtoolsselenium4

Perform value validation with lambda expression


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?


Solution

  • 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
       }
    }