2

I want to pass dynamic variables of type Enum from a scenario step to a graphql mutation. My current implementation:

  Scenario: Update device settings
    ...
    * def wifi = ON
    * def bluetooth = OFF
    * def query = read('update-device-settings.graphql')
    * def variables = { wifi: #(wifi), bluetooth: #(bluetooth) }
    When request { query: #(query), variables: #(variables) }
    When method POST
    ...
mutation ($wifi: __EnumValue!, $bluetooth: __EnumValue!) {
    updateDeviceSettings(
        input: {
            wifi: $wifi,
            bluetooth: $bluetooth,
        }
    )
}

But I already get this error in the scenario:

* def wifi = ON
>>>> js failed:
01: ON
<<<<
org.graalvm.polyglot.PolyglotException: ReferenceError: "ON" is not defined
- <js>.:program(Unnamed:1)

How can I create an pass enum values? Or could I pass string values (e.g. 'ON') and get it parsed in the Graphql file?

EDIT: These values for wifi and bluetooth are not strings. This is the working cURL request:

curl \
--header "Content-Type: application/json" \
--request POST \
--data '{ "query": "mutation { updateDeviceSettings( input: { wifi: ON, bluetooth: OFF } ) }" }' https://ip:port/path

2 Answers2

0

There's no such thing as an Enum type in Karate. Perhaps you mean strings and the other 2 are boolean and number (same as JS / JSON).

And please use quotes around your strings:

* def wifi = 'ON'
* def bluetooth = 'OFF'
* def variables = { wifi: '#(wifi)', bluetooth: '#(bluetooth)' }
* request { query: '#(query)', variables: '#(variables)' }
* method post

Also refer this other answer for other ideas: https://stackoverflow.com/a/69349118/143475

Tip: Finally everything has to be sent as a string in the request, and your server may "interpret" strings as enums, but Karate is not concerned with that at all. If you are still stuck, take some help from your "server side" team, or edit your question with a working cURL request.

EDIT after seeing your cURL example. So as I said, a GraphQL query is a plain string.

* def query = "mutation { updateDeviceSettings( input: { wifi: ON, bluetooth: OFF } ) }"
* request { query: '#(query)' }
* method post

So try that, it should work, and you don't have variables. Read the other answer I linked and you should be on your way.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Peter Thomas
  • 54,465
  • 21
  • 84
  • 248
  • I edited my question with the working cURL. Besides, the values are not string, so there's no need to use quotes. – Stan Allosserie Sep 28 '21 at 14:28
  • @StanAllosserie see my edit, it should work. – Peter Thomas Sep 28 '21 at 14:35
  • I see now that I had two problems, which are now solved: 1) Passing enum values from a scenario to graphql is possible if they're not assigned to a variable, indeed. That also goes for passing enum values from scenario to scenario, in which case they essentially _become_ variables in the latter scenario, which then can be passed on to graphql as `* def variables = { wifi : #(wifi)} }`, (not `'#(wifi)'`). – Stan Allosserie Sep 29 '21 at 09:36
  • 2) Having enum values as graphql parameters also proved to be problematic, as my server wouldn't accept string values. I solved this by placing the enum definitions in a file (in my case a Kotlin file) in the same directory as the graphql file, like so: `internal enum class Wifi { ON, OFF, UNSUPPORTED}`. – Stan Allosserie Sep 29 '21 at 09:36
  • 1
    for anyone reading this, I don't recommend the use of `wifi: #(wifi)` *without* quotes - and don't understand why that didn't work for you, but hey - whatever works – Peter Thomas Sep 29 '21 at 09:41
0

Here is how i handle graphQL: Create a separate graphql file for each mutation/query.

mutation createUser ($input: User ) {
    createUser(input: $input)
}

Then in your feature file You will have something like this:

* def query = read ('graphQL/createUser.graphql')
* def variables = {"input":{"username": "Admin"}}
* request { query : '#(query)', variables : '#(variables)'}

Your query/mutation files and input can be just copy/paste from request on web app. Instead of ($wifi: __EnumValue!, $bluetooth: __EnumValue!) use object from graphql schema

senaid
  • 534
  • 2
  • 8