Search code examples
javaseleniumselenium-chromedriverwebdrivergoogle-chrome-devtools

ChromeDevTools in selenium, waiting for response bodies


I need to work on ajax response, that is one of responses received upon visiting a page. I use selenium dev tools and java. I create a listener, that intercepts a specific request and then I want to work on response it brings. However I need to setup static wait, or else selenium don't have time to save RequestId. I read Chrome Dev Tools documentation, but it's a new thing for me. I wonder if there is a method that would allow me to wait for this call to be completed, other than the static wait.

Here is my code:

    @Test(groups = "test")
    public void x() throws InterruptedException, JsonProcessingException {
        User user = User.builder();
        ManageAccountStep manageAccountStep = new ManageAccountStep(getDriver());
        DashboardPO dashboardPO = new DashboardPO(getDriver());
        manageAccountStep.login(user);
        DevTools devTools = ((HasDevTools) getDriver()).maybeGetDevTools().orElseThrow();
        devTools.createSessionIfThereIsNotOne();
        devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
        // end of boilerplate
        final RequestId[] id = new RequestId[1];
        devTools.addListener(Network.responseReceived(), response -> {
            log.info(response.getResponse().getUrl());
            if (response.getResponse().getUrl().contains(DESIRED_URL)){
                id[0] = response.getRequestId();
            }
        });
        dashboardPO
                .clickLink(); // here is when my DESIRED_URL happens 
        Utils.sleep(5000); // Something like Thread.sleep(5000)
        String responseBody = devTools.send(Network.getResponseBody(id[0])).getBody();
        // some operations on responseBody
        devTools.clearListeners();
        devTools.disconnectSession();
    }

If I don't use 5 seconds wait id variable gets never assigned and I null pointer exception requestId is required. During these 5 seconds log.info prints all api calls that are happening and it almost always finds my id. I would like to refrain from static wait though. I am thinking about something similiar to maybe jQuery.active()==0, but my page doesn't use jQuery.


Solution

  • You may try custom function Explicit Wait. Something like this:

    public String getResponseBody(WebDriver driver, DevTools devTools) {
        return new WebDriverWait(driver,5)
          .ignoring(NullPointerException.class)
          .until(driver -> 
          devTools.send(Network.getResponseBody(id[0])).getBody());
    }
    

    So, it won't wait for all 5 seconds. The moment it got the data, it would come of out of the until method. Also add whichever Exception that was coming up here.

    Has put these lines of code as separate method because, devTools object is locally defined. In order to use them inside this anonymous inner function, it has to be final or effectively final.