K6: JavaScript spread operator throws error with params object

Created on 29 Oct 2018  路  7Comments  路  Source: loadimpact/k6

It would be nice to have the ability to configure a default params object with some common behaviors (authorization, tags, etc.) that request methods can overwrite using the spread operator as necessary.

For example, this is valid syntax in ES6.

let params = {
    headers: {
        "Content-Type": "Application/JSON",
    },
    timeout: 2000
};

let override = { ...params, timeout: 5000};

console.log(override);
// { headers: { 'Content-Type': 'Application/JSON' }, timeout: 5000 }

When I attempt the same behavior in a K6 test script, I get this error message:
image

Code sample to reproduce: google-search.js

import { check } from 'k6';
import http from 'k6/http';

export default function () {
    let params = {
        headers: {
            "Content-Type": "Application/JSON",
        },
        timeout: 5000
    };
    let requests = {
        "googleSearchWithQueryString": {
            method: "GET",
            url: `https://www.google.com/search?q=k6`,
            params: { ...params, timeout: 1000}
        },        
    };

    let responses = http.batch(requests);

    check(responses["googleSearchWithQueryString"], {
        "add concept code result was 200": res => res.status === 200
    });

}
enhancement help wanted js-compat

Most helpful comment

I just wanted to add my +1 to this issue because I've run into the same problem on my end. The spread operator is very convenient for having default tags or headers and just extending them on specific requests as I tried here:
07_11_2019__11:34:17

All 7 comments

k6 uses goja as JS VM and goja is only 5.1 ES compliant :(. We also use Babel to transform ES6 to ES5.1 JS but that obviously doesn't work always. There are two plugins for this but I will have to test them before I can tell you if it's going to work.
Can you try Object.assign in the meantime?

Thanks. That makes sense as a viable workaround. The fix ends up looking like this

import { check } from 'k6';
import http from 'k6/http';

export default function () {
    let params = {
        headers: {
            "Content-Type": "Application/JSON",
        },
        timeout: 5000
    };
    let requests = {
        "googleSearchWithQueryString": {
            method: "GET",
            url: `https://www.google.com/search?q=k6`,
            params: Object.assign({}, params, {timeout: 1000})
        },        
    };

    let responses = http.batch(requests);

    check(responses["googleSearchWithQueryString"], {
        "add concept code result was 200": res => res.status === 200
    });

}

// { headers: Object { Content-Type: "Application/JSON" }, timeout: 1000 }

Nice! Going to keep this open for when we decide to actually have the spread operator

I just wanted to add my +1 to this issue because I've run into the same problem on my end. The spread operator is very convenient for having default tags or headers and just extending them on specific requests as I tried here:
07_11_2019__11:34:17

More fuel to the fire here. Spread operators ftw! Also thank you for sharing the Object.assign() workaround. I was not aware of that myself.

+1, would really like to see ES6 support.

To be fair, we have ES6 support. k6 supports the spread operator in function calls and array expansion, it just doesn't work for object literals, which is something new from ECMAScript 2018.

export default function () {
    console.log(...["this", "works"]);

    console.log(...[...["this", "also"], "works"]);

    // This doesn't work though
    //let a = { ...{ foo: "bar" }, test: "mest" }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

euclid1990 picture euclid1990  路  3Comments

athoune picture athoune  路  3Comments

Jonne picture Jonne  路  4Comments

StephenRadachy picture StephenRadachy  路  3Comments

ppcano picture ppcano  路  3Comments