4

I am using the k6 Load Testing Tool for the first time.

I send a GET request and html is sent in the response. I then need to extract some values from this html.

What is the best way of doing this in HTML? I have seen in the documentation that there are the following 3 commands that could possibly be of help:

Response.body
Selection.find(selector)
Response.json([selector])

The HTML is shown below. I want to extract the values of csrf and transId

<html lang="en">

<head>
    <link rel="icon" href="data:;base64,iVBORw0KGgo=">
    <script data-container="true" nonce="ekqlmSlKlpMlCSDxgP6erg==">
        
        var SETTINGS = {

         "csrf": "I NEED THIS VALUE",
         "transId": "I ALSO NEED THIS VALUE",
        };

    </script>
    
</head>

<body>
</body>

</html>

I think I could do it using Response.body and then searching for a substring. Is this the best way of doing it?

greybeard
  • 2,249
  • 8
  • 30
  • 66
Matt
  • 773
  • 2
  • 15
  • 30

2 Answers2

5

Firstly, to get the contents of the script tag, you can do

  const doc = parseHTML(res.body);

  const script = doc.find('head script');
  const scriptContent = script.text();

Now to extract needed values from

  var SETTINGS = {

     "csrf": "I NEED THIS VALUE",
     "transId": "I ALSO NEED THIS VALUE",
    };

you will have to do some string manipulation that is not recommended for a load test script. But you could

a.substr(28, 15)

to get csrf value and

a.substr(57, 22)

to get transId value.

Aalok
  • 553
  • 8
  • 21
0

Because in this case you have javascript you could evaluate it and get the values as

import html from "k6/html";
export default function () {
    var res = `<html lang="en">

        <head>
            <link rel="icon" href="data:;base64,iVBORw0KGgo=">
            <script data-container="true" nonce="ekqlmSlKlpMlCSDxgP6erg==">


                var SETTINGS = {

                             "csrf": "I NEED THIS VALUE",
                             "transId": "I ALSO NEED THIS VALUE",
                            };

        </script>

        </head>

        <body>
        </body>

        </html>
    `
    var b =  html.parseHTML(res).find("script").text();
    console.log(b);
    var settings = eval(b + ";SETTINGS;");
    console.log(settings.csrf);
}

This way you don't need to know the exact places of the values and you can get more values out of it ... easily ;).

As the other answered mentioned, this is probably not a good idea inside a load testing script - especially the load testing part - if this is in some setup code it's probably fine.

Note: the ;SETTINGS; is because eval returns the last value so we need to put SETTINGS in the end ;)

Alternatively, you could write a helper function to do what Aalok did by hand:

export default function () {
    var res = `<html lang="en">

        <head>
            <link rel="icon" href="data:;base64,iVBORw0KGgo=">
            <script data-container="true" nonce="ekqlmSlKlpMlCSDxgP6erg==">


                var SETTINGS = {

                             "csrf": "I NEED THIS VALUE",
                             "transId": "I ALSO NEED THIS VALUE",
                            };

        </script>

        </head>

        <body>
        </body>

        </html>
    `
    console.log(getLabel(res, "csrf"));
    console.log(getLabel(res, "transId"));
}

function getLabel(content, label) {
    var start = content.indexOf('"'+label+'":') + label.length + 3;
    var nextComma = content.indexOf(',', start);
    var nextCurly = content.indexOf('}', start);
    var end = Math.min(nextComma,nextCurly);
    return content.substring(start,end)
}

You may need to trim some spaces or/and "