AnWeber / vscode-httpyac

Quickly and easily send REST, Soap, GraphQL, GRPC, MQTT and WebSocket requests directly within Visual Studio Code
https://marketplace.visualstudio.com/items?itemName=anweber.vscode-httpyac
MIT License
246 stars 23 forks source link

chai require from .http not supported #268

Open zawiasam opened 8 months ago

zawiasam commented 8 months ago

Can't import chai for assertions

after sending request

Host: postman-echo.com

{{
    const assert = require("chai").assert
      , foo = 'bar'
      , beverages = { tea: [ 'chai', 'matcha', 'oolong' ] };
    test("chai", function () {
        assert.typeOf(foo, 'string'); // without optional message
    })
}}

error from vc extension

/Users/maciek/source/test/node_modules/chai/chai.js from /Users/maciek/source/test/Untitled-1.http not supported. Instead change the require of chai.js in /Users/maciek/source/test/Untitled-1.http to a dynamic import() which is available in all CommonJS modules. at Function.<anonymous> (node:electron/js2c/node_init:2:13357) at h._load (/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js:173:5634) at n._load (/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js:170:29786) at t._load (/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js:135:35289) at s (/Users/maciek/.vscode/extensions/anweber.vscode-httpyac-6.11.6/dist/extension.js:196:2430) at Object.userJS (/Users/maciek/source/test/Untitled-1.http:5:20) at CQ (/Users/maciek/.vscode/ex...

from CLI

Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/maciek/source/test/node_modules/chai/chai.js from /Users/maciek/source/test/Untitled-1.http not supported.
Instead change the require of chai.js in /Users/maciek/source/test/Untitled-1.http to a dynamic import() which is available in all CommonJS modules.
    at s (/Users/maciek/.nvm/versions/node/v18.16.0/lib/node_modules/httpyac/dist/index.js:6:2432)
    at Object.userJS (/Users/maciek/source/test/Untitled-1.http:5:20)
    at Yt (/Users/maciek/.nvm/versions/node/v18.16.0/lib/node_modules/httpyac/dist/index.js:6:2730)
    at kt (/Users/maciek/.nvm/versions/node/v18.16.0/lib/node_modules/httpyac/dist/index.js:6:6167)
    at Object.action (/Users/maciek/.nvm/versions/node/v18.16.0/lib/node_modules/httpyac/dist/index.js:6:5438)
    at n.trigger (/Users/maciek/.nvm/versions/node/v18.16.0/lib/node_modules/httpyac/node_modules/hookpoint/dist/index.js:1:2866)
    at async t.execute (/Users/maciek/.nvm/versions/node/v18.16.0/lib/node_modules/httpyac/dist/index.js:2:52568)
    at async mp (/Users/maciek/.nvm/versions/node/v18.16.0/lib/node_modules/httpyac/dist/index.js:119:33932)
    at async Tc (/Users/maciek/.nvm/versions/node/v18.16.0/lib/node_modules/httpyac/dist/index.js:119:34177)
    at async Eo (/Users/maciek/.nvm/versions/node/v18.16.0/lib/node_modules/httpyac/dist/index.js:119:33684)
    at async Command._c (/Users/maciek/.nvm/versions/node/v18.16.0/lib/node_modules/httpyac/dist/index.js:119:43602)
    at async Command.parseAsync (/Users/maciek/.nvm/versions/node/v18.16.0/lib/node_modules/httpyac/node_modules/commander/lib/command.js:936:5)
    at async Object.Qc (/Users/maciek/.nvm/versions/node/v18.16.0/lib/node_modules/httpyac/dist/index.js:119:47517) {
  code: 'ERR_REQUIRE_ESM',
  handled: true
}

package.json

{
  "dependencies": {
    "chai": "^5.1.0"
  }
}
AnWeber commented 8 months ago

@zawiasam The problem is that chai switched to ESM with v5 (see Release Notes). This is not supported by the require. You would have to use import(). However, I do not currently provide this. I first have to learn how to do it. The current workaround would be to downgrade to chai@4.x

zawiasam commented 8 months ago

@AnWeber Maybe I could help somehow, any hint where I could to start?

AnWeber commented 8 months ago

@zawiasam With pleasure. It is actually also encapsulated and can therefore be worked on without the big picture. But the problem is complicated enough. The method runScript is used to run some text Content as NodeJS Script. In this Script access to all variables is needed and exports needs to be added to the variables after script execution. Unfortunately, this method does not support ESM or the use of import. For import() setting importModuleDynamically would apparently be necessary, but this is new territory for me. Another special feature is that the import has to be "bent", or that's my idea. The code acts within httpyac package and therefore has access to httpyac dependencies. In order to have access to deps from the target package, this must be bent. Hence the const mod = createModule(filename);hack to get require calls working. In the Contributing would be a guide on how to debug it, but another approach would be to extract the code and make it run independently and then integrate the features.

alekdavisintel commented 2 months ago

@zawiasam Did you figure out how to do this?

@AnWeber What would you recommend to use for testing complex assertions (e.g. check if an object list returned with response contains elements with specific properties, such as expect(response.parsedBody).to.deep.include.members([{ id: 123 }, {id: 456']))? Is there an alternative to chai? If not, what are the steps to use a downgraded version of chai? It would be really helpful if a richer assertion library (chai 4.x or whatever) were bundled with httpYac (like these: https://httpyac.github.io/guide/scripting.html#require), because assertions are the essential part of what the API testing and if it requires manual steps, it would complicate usage and increase support calls.

alekdavis commented 2 months ago

@AnWeber I manually installed chai 4.4.1:

image

Restarted VSCode, but I'm still getting an error that the module is missing:

image

Did I miss a step?

AnWeber commented 2 months ago

@alekdavisintel You are now right that Chai should be bundled. My idea of the tool initially came from a different direction. Just a small Postman replacement. The ideas I got from issues, have changed it. Using chai@v4 is supported. Only v5 is broken because of esm. NodeJS v22 brings better support to also require esm modules. Maybe this Problem is solved. I will retry a solution next week. But I try to survive the heat in italy at the moment

Did i muss a step?

Probably Not. That is the way I used it

alekdavis commented 1 month ago

@AnWeber I just installed the latest version of NodeJS 22.x, but I'm still getting errors trying to include chai:

image

image

So, looks like Node v22 does not fix this.

AnWeber commented 1 month ago

You need to enable Support for ESM require, or you could Install v23 where this Support is active by default

https://nodejs.org/en/blog/release/v23.0.0

alekdavis commented 1 month ago

Sweet. Thank you so much.

If anyone is interested. What you need to do is:

  1. Upgrade NodeJS to v23.
  2. Install chai: npm install chai (see P.S. below).
  3. Use require for the chai functionality you want to use. The following code is working for me:
@host=https://httpbin.org
@value=abc

### Demo CHAI expect
GET /anything?value={{value}}
{{
  const { expect } = require('chai');
  test('EXPECT status code 200', () => {
    expect(response.statusCode).to.equal(200);
  });
}}

### Demo CHAI assert
GET /anything?value={{value}}
{{
  const { assert } = require('chai');
  test('ASSERT status code 200', () => {
    assert.equal(response.statusCode, 200);
  });
}}

### Demo CHAI should
GET /anything?value={{value}}
{{
  require('chai').should();
  test('SHOULD status code 200', () => {
    response.statusCode.should.be.equal(200);
  });
}}

I will do a bit more testing (I have several versions of chai installed so need to clean it up and make sure it still works, which it should) and add chai examples and instructions to my https://github.com/alekdavis/httpyac-extras repo.

Thanks again. This is awesome.

P.S. I should have mentioned that examples above use chai@4.5.0, which needs to be added either globally or to the project (I tried using import for chai@5.x, but could not make it work). So, the project's package.json should look like:

{
  "devDependencies": {
    "chai": "^4.5.0"
  }
}

Use npm install chai@4.5.0 (or use the most recent version of pre-5.x version of `chai). I'm still not 100% clear how versioning here works, so will need to do more testing.

alekdavis commented 1 month ago

Okay, a couple of tips for the the novices (after a few tests I did):

Once you do this, the code above will work. As I said, I will add this info along with the chai package and demos to the https://github.com/alekdavis/httpyac-extras repo.

I hope chai gets bundled with httpYac at some point to avoid the whole hassle, but for now this should work just fine if you do it right.

alekdavis commented 1 month ago

I added some samples to https://github.com/alekdavis/httpyac-extras/blob/main/Tests/Demos/demo-7-Asserts-Chai.http