How to get the downloaded xlsx file from the api endpoint in karate?

I have an endpoint that downloads an xlsx file. In my test, I need to check the content of the file (not comparing the file with another file, but reading the content and checking). I am using karate framework for testing and I am trying to use apache POI for working with the excel sheet. However, the response I get from karate when calling the download endpoint is a String. For creating an excel file with POI I need an InputStream or the path to the actual file. I have tried the conversion, but it does not work.

I guess I am missing some connection here, or maybe the conversion is bad, I am new to karate and to the whole thing. I appreciate any help, thanks!

 Given url baseUrl
    Given path downloadURI
     When method GET
     Then status 200
    And match header Content-disposition contains 'attachment'
    And match header Content-disposition contains 'example.xlsx'
    And match header Content-Type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

        * def value= FileChecker.createExcelFile(response)
        * print value

And the Java code:

public static String createExcelFile(String excel) throws IOException, InvalidFormatException {
        InputStream stream = IOUtils.toInputStream(excel, Charset.forName("UTF-8"));
        Workbook workbook = WorkbookFactory.create(stream);
        return ("Workbook has " + workbook.getNumberOfSheets() + " Sheets : ");
    }

When running the scenario, I get the following error: javascript evaluation failed: FileChecker.createExcelFile(response), java.io.IOException: Failed to read zip entry source

When testing the same endpoint in Postman, I am getting a valid excelsheet.


In Karate 0.9.X onwards you have a responseBytes variable which will be raw bytes, which may be what you need.

* def value = FileChecker.createExcelFile(responseBytes)

And you can change your method signature to be:

public static String createExcelFile(byte[] excel) {}

You should be easily able to convert a byte array to an InputStream and take it from there.

P.S. just saying that it "works in Postman" is not helpful :P