When I run tests using `ng test` , I get the follo...
# pact-js
b
When I run tests using
ng test
, I get the following error:
Copy code
Generating browser application bundles (phase: building)...[15:53:38.170] INFO (15372): pact-node@10.18.0: Creating Pact Server with options: 
{"cors":true,"spec":3,"port":1234,"log":"C:\\Git\\st-devops-testfullapp\\st-tst-testapp-front\\logs\\mockserver-integration.log","dir":"C:\\Git\\st-devops-testfullapp\\st-tst-testapp-front\\pacts","pactFileWriteMode":"overwrite","ssl":false,"host":"localhost"}
[15:53:42.677] ERROR (15372): pact-node@10.18.0: Pact Binary Error: The system cannot execute the specified program.

[15:53:42.679] WARN (15372): pact-node@10.18.0: Pact exited with code 1.
Any idea what might cause this? I see that my tests are started afterwards, but they obviously fail because the mock server doesn't want to start
No logs are being created, so that doesn't provide additional information
y
i would imagine as you are on windows and using an old version of pact-js, the bundled ruby runtime isnt able to open. they are in the standalone folder in node_modules/@pact-foundation/pact-core worth checking if you can execute that and also check which version of the standalone it is using
🧡 1
b
I’ll have a look tomorrow, thanks Saf!
Would you recommend using newer / other libraries? Given that this app is on Angular v16 which I’m not willing to change (it’s a demo app, not worth the hassle at the moment)
y
hmm so that version of pact node we recently published with an updated version of the standalone https://www.npmjs.com/package/@pact-foundation/pact-node?activeTab=versions what version of node are you using in the tests? i know there were recently issues on windows with the cli tools in pact-core due to a windows cve, and we had to put out a fix in that check in the node modules, to see if the standalone binaries downloaded and can be opened manually. if so then the issue is in the node wrapper. can confirm later by pulling down the package on one of my windows boxes
oddly the pact ruby standalone package 2.4.1 package works fine when downloaded directly, but there is certainly an issue with executing the downloaded and unarchived package through pact-js. if i replace the downloaded standalone via pact-js with one downloaded myself that works fine. so you can download the binary yourself from here https://github.com/pact-foundation/pact-ruby-standalone/releases/tag/v2.4.1 and set the download location in your project https://github.com/pact-foundation/pact-js-core/tree/pact-node?tab=readme-ov-file#pact-download-location that should hopefully get you out of a bind
m
ah, Karma. So we deprecated that package about 2 years (see deprecation notice here: https://github.com/pact-foundation/karma-pact and discussion here: https://github.com/pact-foundation/pact-js/issues/626). It’s possible that simply upgrading the underlying pact-node package will just work. However the real issue is that moving to our core engine makes supporting non node-based packages difficult, because we need to be able to create ports, interact with the file system etc. We would need to move to a client-server model, so that packages running in e.g. karma can communicate to a server.
Would you recommend using newer / other libraries? Given that this app is on Angular v16 which I’m not willing to change (it’s a demo app, not worth the hassle at the moment)
If it’s possible Bas, I’d recommend moving your Pact tests for the Angular project to something like Mocha, Jest or Vite. These run in node and are well supported for Pact. I think you could still run the older version of ng, but just run the tests in a modern node-based testing framework
b
OK, I think I'm making progress here. I've replaced the old Pact dependencies with
@pact-foundation/pact
and I'm using Jest now. Still, it seems my Pact mock server doesn't start properly. Here's the
debug
logs (removed most of the updated catalogue entries, I don't think those are relevant):
Copy code
> st-tst-testapp-front@1.0.0 test:pact
> jest --config ./jest.config.pact.js

[13:53:51.240] [34mDEBUG[39m (2508): [36mpact-core@15.1.0: Initalising native core at log level 'debug'[39m
[13:53:51.244] [34mDEBUG[39m (2508): [36mpact-core@15.1.0: binding path #0: : attempting to load native module from: 

 - C:\Git\st-devops-testfullapp\st-tst-testapp-front\node_modules\@pact-foundation\pact-core\prebuilds\win32-x64 
   source: pact-js-core binding lookup 

 - You can override via PACT_PREBUILD_LOCATION
[39m
[13:53:51.251] [32mINFO[39m (2508): [36m0.4.21: pact native library successfully found, and the correct version[39m
2024-07-04T11:53:51.279714Z DEBUG ThreadId(01) pact_ffi::mock_server::handles: Failed to parse the value, treating it as a plain string: expected value at line 1 column 1
2024-07-04T11:53:51.281026Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $
2024-07-04T11:53:51.281049Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Configuring a normal object
2024-07-04T11:53:51.281389Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.address
2024-07-04T11:53:51.281399Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: detected pact:matcher:type, will configure a matcher
2024-07-04T11:53:51.281451Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.country
2024-07-04T11:53:51.281456Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: detected pact:matcher:type, will configure a matcher
2024-07-04T11:53:51.281466Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.information
2024-07-04T11:53:51.281471Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: detected pact:matcher:type, will configure a matcher
2024-07-04T11:53:51.281478Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.name
2024-07-04T11:53:51.281482Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: detected pact:matcher:type, will configure a matcher
[13:53:51.281] [34mDEBUG[39m (2508): [36mpact@13.1.0: Setting up Pact mock server with Consumer "st-tst-testapp-front" and Provider "st-tst-testapp-api"
        using mock service on Port: "4010"[39m
2024-07-04T11:53:51.282257Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries:
core/transport/http
core/transport/https
2024-07-04T11:53:51.282317Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries:
...
2024-07-04T11:53:51.282374Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries:
..
2024-07-04T11:53:51.282796Z DEBUG ThreadId(01) pact_mock_server::mock_server: Started mock server on 127.0.0.1:4010
[13:53:51.282] [34mDEBUG[39m (2508): [36mpact@13.1.0: mock service started on port: 4010[39m
  console.error


    [0m [90m 30 |[39m
     [90m 31 |[39m   afterEach([36masync[39m () [33m=>[39m {
    [31m[1m>[22m[39m[90m 32 |[39m     [36mawait[39m provider[33m.[39mverify()[33m;[39m
     [90m    |[39m                    [31m[1m^[22m[39m
     [90m 33 |[39m   })[33m;[39m
     [90m 34 |[39m
     [90m 35 |[39m   afterAll([36masync[39m () [33m=>[39m {[0m

      at Pact.Object.<anonymous>.Pact.verify (node_modules/@pact-foundation/src/httpPact/index.ts:209:15)
      at src/app/contract-tests/userservice.spec.pact.ts:32:20
      at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (node_modules/zone.js/bundles/zone.umd.js:412:30)
      at ProxyZoneSpec.Object.<anonymous>.ProxyZoneSpec.onInvoke (node_modules/zone.js/bundles/zone-testing.umd.js:300:43)
      at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (node_modules/zone.js/bundles/zone.umd.js:411:56)
      at Zone.Object.<anonymous>.Zone.run (node_modules/zone.js/bundles/zone.umd.js:166:47)
      at Object.wrappedFunc (node_modules/zone.js/bundles/zone-testing.umd.js:789:34)

  console.error
    [31mPact verification failed![39m

    [0m [90m 30 |[39m
     [90m 31 |[39m   afterEach([36masync[39m () [33m=>[39m {
    [31m[1m>[22m[39m[90m 32 |[39m     [36mawait[39m provider[33m.[39mverify()[33m;[39m
     [90m    |[39m                    [31m[1m^[22m[39m
     [90m 33 |[39m   })[33m;[39m
     [90m 34 |[39m
     [90m 35 |[39m   afterAll([36masync[39m () [33m=>[39m {[0m

      at Pact.Object.<anonymous>.Pact.verify (node_modules/@pact-foundation/src/httpPact/index.ts:210:15)
      at src/app/contract-tests/userservice.spec.pact.ts:32:20
      at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (node_modules/zone.js/bundles/zone.umd.js:412:30)
      at ProxyZoneSpec.Object.<anonymous>.ProxyZoneSpec.onInvoke (node_modules/zone.js/bundles/zone-testing.umd.js:300:43)
      at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (node_modules/zone.js/bundles/zone.umd.js:411:56)
      at Zone.Object.<anonymous>.Zone.run (node_modules/zone.js/bundles/zone.umd.js:166:47)
      at Object.wrappedFunc (node_modules/zone.js/bundles/zone-testing.umd.js:789:34)

  console.error
    [31mTest failed for the following reasons:
    
      Mock server failed with the following mismatches:
    
    	0) The following request was expected but not received: 
    	    Method: GET
    	    Path: /api/v1/DelaUser/100[39m

    [0m [90m 30 |[39m
     [90m 31 |[39m   afterEach([36masync[39m () [33m=>[39m {
    [31m[1m>[22m[39m[90m 32 |[39m     [36mawait[39m provider[33m.[39mverify()[33m;[39m
     [90m    |[39m                    [31m[1m^[22m[39m
     [90m 33 |[39m   })[33m;[39m
     [90m 34 |[39m
     [90m 35 |[39m   afterAll([36masync[39m () [33m=>[39m {[0m

      at Pact.Object.<anonymous>.Pact.verify (node_modules/@pact-foundation/src/httpPact/index.ts:211:15)
      at src/app/contract-tests/userservice.spec.pact.ts:32:20
      at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (node_modules/zone.js/bundles/zone.umd.js:412:30)
      at ProxyZoneSpec.Object.<anonymous>.ProxyZoneSpec.onInvoke (node_modules/zone.js/bundles/zone-testing.umd.js:300:43)
      at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (node_modules/zone.js/bundles/zone.umd.js:411:56)
      at Zone.Object.<anonymous>.Zone.run (node_modules/zone.js/bundles/zone.umd.js:166:47)
      at Object.wrappedFunc (node_modules/zone.js/bundles/zone-testing.umd.js:789:34)

[13:53:51.350] [34mDEBUG[39m (2508): [36mpact@13.1.0: cleaning up old mock server on port 4010[39m
2024-07-04T11:53:51.350980Z DEBUG ThreadId(01) pact_matching::metrics: Could not get the tokio runtime, will not send metrics - there is no reactor running, must be called from the context of a Tokio 1.x runtime
2024-07-04T11:53:51.351015Z DEBUG ThreadId(01) pact_mock_server::server_manager: Shutting down mock server with ID ad729777-58ae-427a-b956-b0714f446f72 - MockServerMetrics { requests: 0, requests_by_path: {} }
2024-07-04T11:53:51.351049Z DEBUG ThreadId(01) pact_mock_server::mock_server: Mock server ad729777-58ae-427a-b956-b0714f446f72 shutdown - MockServerMetrics { requests: 0, requests_by_path: {} }
2024-07-04T11:53:51.351109Z DEBUG tokio-runtime-worker hyper::server::shutdown: signal received, starting graceful shutdown
Any ideas?
I've asked someone on Mac and with access to the repo to run the tests, too, to see if it's a Windows 'feature'..
I've added some logging to my tests and I can see that it is invoking
<http://localhost:4010/api/v1/DelaUser/100>
(the same port where the Pact mock server is running), and the interaction is defined as
Copy code
beforeAll(async () => {
      await provider.addInteraction({
        state: `user 100 exists`,
        uponReceiving: 'a request to GET a user',
        withRequest: {
          method: 'GET',
          path: `/api/v1/DelaUser/${userId}`,
        },
        willRespondWith: {
          status: 200,
          body: {
            id: expectedUser.id,
            name: Matchers.string(expectedUser.name),
            address: Matchers.string(expectedUser.address),
            country: Matchers.string(expectedUser.country),
            information: Matchers.string(expectedUser.information)
          },
        },
      });
which looks good to me? (the value of
${userId}
is
100
)
Yet the Jest test output keeps telling me
Copy code
Contract tests for user service › GET a user › should get user with ID 100                                                                      
                                                                                                                                                    
    expect(received).toEqual(expected) // deep equality

    Expected: {"address": "Valid address", "country": "Valid country", "id": 100, "information": "Valid information", "name": "Valid name"}
    Received: undefined
(which is the root of the problem, but I don't see why it doesn't return anything)
y
is the example public at all?
b
No, but I can share it with you, it’s just a demo app. Will DM you a GitHub link soon
y
thanks for sharing Bas, looks like we may have got to bottom of it 🙂