#E2E Testing with Pactum

45 messages · Page 1 of 1 (latest)

ripe skiff
#

Hello, I'm tired as hell with debugging it, so I need help from you.

So I have request which works perfectly when it's being called with Altair, body looks like:

{"query":"query products {\n  products {\n    items {\n      id\n      name\n    }\n  }\n}","variables":{},"operationName":"products"}

And it works. When I'm trying to send request with pactum it's showing me error:

The query you want to parse is using variables. This means that you have to supply for every variable that is used in the query a corresponding value. You can parse these values as a second parameter on the options object, on the \"variables\" key.

Body of Pactum thing:

"body": {
        "query": "\n              query products {\n                products {\n                  items {\n                    id\n                    name\n                  }\n                }\n              }\n            ",
        "variables": {}
      },```

You can see this is the same 😦 I'm running out of ideas...

I'm using Pactum because I was unable to setup it with supertest, I was getting always `BAD REQUEST 404` 😦
little jolt
#

operationName is missing in the second example

ripe skiff
#

Yea I know, but it should work anyway, if I move this example to any http client (postman, thunder) it works

#

but if pactum sends it it doesn't

little jolt
#

Okay, can you show some of the actual code?

ripe skiff
#

Yea sure, I can show my test code

#
import * as pactum from 'pactum';
import { AppModule } from '../../src';
import { INestApplication, ValidationPipe } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { gql } from 'graphql-request';

describe(`GraphQL AppResolver (e2e) - ${process.env.INTEGRATION_MODULE}`, () => {
  let app: INestApplication;
  let url: string;

  beforeAll(async () => {
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    app = moduleFixture.createNestApplication();
    app.useGlobalPipes(new ValidationPipe());
    await app.listen(0);
    url = await app.getUrl();
    pactum.request.setBaseUrl(url.replace('[::1]', 'localhost'));
  });

  afterAll(async () => {
    await app.close();
  });

  describe('/graphql', () => {
    describe('cart', () => {
      it('should create new empty cart', async () => {
        return await pactum
          .spec()
          .post('/graphql')
          .withGraphQLQuery(
            gql`
              mutation createEmptyCart {
                createEmptyCart
              }
            `
          )
          .withGraphQLVariables({})
          .expectStatus(200)
          .expectJsonLike({
            data: {
              createEmptyCart: '$V.length > 0',
            },
          });
      });
    });

    describe('products', () => {
      it('should return product list', async () => {
        return await pactum
          .spec()
          .post('/graphql')
          .withGraphQLQuery(
            gql`
              query products {
                products {
                  items {
                    id
                    name
                  }
                }
              }
            `
          )
          .withGraphQLVariables({})
          .expectStatus(200)
          .expectJsonLike({
            data: {
              products: {
                items: '$V.length < 0',
              },
            },
          });
      });
    });
  });
});
#

first test works like a charm

little jolt
#

Have you tried sending the raw payload in a regular post without the gql tag? I don't really see anything wrong

ripe skiff
#

yeah

#

I have even tried using .sendBody instead of graphql

#

and errors were the same

little jolt
#

Hm, I have no idea. I'm probably try with simpler queries until I figure out what's wrong.

ripe skiff
#

I will try to run test for mutation that has only one variable possible

#

maybe it wants me to pass all possible variables

#
    describe('route', () => {
      it('route', async () => {
        return await pactum
          .spec()
          .post('/graphql')
          .withGraphQLQuery(
            gql`
              query route($url: String!, $customAttributes: [String!]) {
                route(url: $url, customAttributes: $customAttributes) {
                  item {
                    ... on Category {
                      name
                    }
                  }
                }
              }
            `
          )
          .withGraphQLVariables({
            url: 'sypialnia',
            customAttributes: ['test'],
          })
          .expectStatus(200)
          .expectJsonLike({
            data: {
              products: {
                items: '$V.length < 0',
              },
            },
          });
      });
    });
#
{
      "statusCode": 200,
      "headers": {
        "x-powered-by": "Express",
        "access-control-allow-origin": "*",
        "content-type": "application/json; charset=utf-8",
        "content-length": "347",
        "etag": "W/\"15b-ujvMlTdqcc5e1q5YcyaZ4db5JGs\"",
        "date": "Tue, 21 Feb 2023 12:08:15 GMT",
        "connection": "close"
      },
      "body": {
        "errors": [
          {
            "message": "The query you want to parse is using variables. This means that you have to supply for every variable that is used in the query a corresponding value. You can parse these values as a second parameter on the options object, on the \"variables\" key.",
            "status": 500,
            "extensions": {
              "code": "INTERNAL_SERVER_ERROR"
            }
          }
        ],
        "data": null
      }
    }
#

fails anyway 😦

ripe skiff
#

@little jolt I tried to make it with default way

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { INestApplication, ValidationPipe } from '@nestjs/common';
import { AppModule } from '../../src/modules/app/app.module';

describe('GRAPHQL', () => {
  let app: INestApplication;

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    app = moduleRef.createNestApplication();
    app.useGlobalPipes(new ValidationPipe());
    await app.init();
  });

  it(`/GET graphql`, () => {
    return request(app.getHttpServer()).get('/graphql').expect(200);
  });

  afterAll(async () => {
    await app.close();
  });
});
  ● GRAPHQL › /GET graphql

    expected 200 "OK", got 400 "Bad Request"

      18 |
      19 |   it(`/GET graphql`, () => {
    > 20 |     return request(app.getHttpServer()).get('/graphql').expect(200);
         |                                                         ^
      21 |   });
      22 |
      23 |   afterAll(async () => {

But it cannot access this , idk why 😦

little jolt
#

Do you have playground enabled? If not, then there's nothing on the get route iirc

ripe skiff
#

I have

#

but is it enabled when running tests?

little jolt
#

No idea, honestly

ripe skiff
#

I'm near to get sick >.<

little jolt
#

Sometimes I find it's best to sleep on it and somehow it magically works the next day

ripe skiff
#

Yeah, but this is my 3rd try 😂

#

it's something wrong with nestjs itself

little jolt
#

Try creating a minimal reproduction that you can share with us, so somebody could look at it. I don't think there's much more we can do.

ripe skiff
#

umm okay

#

Tried moving to fastify, but nestjs doesn't support fastify + graphql ; _ ;
FastifyError: fastify-plugin: fastify-accepts - expected '3.x' fastify version, '4.13.0' is installed so it's uncompatible with @nestjs/graphql

ripe skiff
#

Okay I found that this error occurs only when apps is created by createTestingModule

ripe skiff
#

I mean, this with variables, I was able to reproduce it on playground

atomic gust
# ripe skiff Okay I found that this error occurs only when apps is created by `createTestingM...

If you might be interested here you can find an test e2e example with pactum: https://github.com/jmcdo29/testing-nestjs/blob/main/apps/graphql-sample/test/app.pactum.e2e-spec.ts

GitHub

A repository to show off to the community methods of testing NestJS including Unit Tests, Integration Tests, E2E Tests, pipes, filters, interceptors, GraphQL, Mongo, TypeORM, and more! - testing-ne...

ripe skiff
#

When app is started normally it works

ripe skiff
atomic gust
#

If I understand correctly you can't start e2e tests with pactum ?

ripe skiff
#

I can't test queries that has variables on it

#

queries without variables are working

#

something goes weird with graphql apollo server when nest app is initialized by Test.createTestingModule

#

When using NestFactory.create everything is okay

#

I'm only unable to e2e test queries with variables

atomic gust
#

If you can, try to create a minimal reproduction so we can take a look at it

ripe skiff
#

okay, will do it after job

atomic gust
#

👍