Enable sinon fakeServer logs - javascript

I'm running several tests where I'm mocking http calls using sinon fake server:
import sinon from 'sinon';
...
const fakeServer = sinon.fakeServer.create();
fakeServer.respondWith('POST', '/myapp/myendpoint/pathparam', [201, { 'Content-Type': 'application/json' }, myPayload]);
...
However the fake server is returning a not found error: [404, { }, (empty string)].
I cannot figure out what's going wrong.
Is there any way to activate some kind of logs that tells me what is going on?
After going over sinon's documentation, I cannot find anything about logs or debug flags.

After inspecting sinon I found that it does not contain the fake server but it is exposing nise/fake-server/.
Then I went over nise and I ended up finding that method to trace the behaviour:
logger: function () {
// no-op; override via configure()
},
So to enable logs in the fake-server the only thing you need to do is to specify a behaviour when you create the fake server:
fakeServer = sinon.fakeServer.create({logger: str => console.log('Fake server', str)});

Related

Why is Sentry.captureMessage not working inside winston Transport log function

I’m trying to get Sentry working with winston (using winston-transport-sentry-node) but it doesn’t seem to work, despite using just a very basic configuration. So out of curiosity, I tried writing my own very simple winston transport class that sends Sentry message for every log like so
import * as Sentry from '#sentry/node'
import * as TransportStream from 'winston-transport'
export class SentryCustomTransport extends TransportStream {
constructor(opts) {
super(opts)
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.ENV_NAME,
sampleRate: 1,
tracesSampleRate: 1,
})
Sentry.captureMessage('Test message constructor')
}
log(info, callback) {
setImmediate(() => {
this.emit('logged', info);
})
console.log('Called log function')
const eventId = Sentry.captureMessage('Test message log')
console.log('Event ID:', eventId)
callback()
}
}
After calling winston logger, I can see an entry in Sentry with message "Test message constructor" but not "Test message log". What's even weirder is I can see the console log prints, including the event ID returned from the calls to Sentry.captureMessage() in the log() function.
I'm not sure what's going on, and kind of have no idea how to make it work. What am I missing here?
winston version: 3.8.2
#sentry/node version: 7.37.2
winston-transport-sentry-node version: 2.7.0
I managed to find the cause of the issue myself. The context of my issue was I'm writing a CLI command in NestJS. Part of the command's implementation (rather incorrectly) include a call to process.exit() function which immediately terminates the command without giving it a chance to do proper clean up (and flushing of data). I'm guessing it's because of this the Sentry module didn't get the chance to actually push the created Sentry event to Sentry server.
Removing the calls to process.exit() and letting the command finishes normally resolves the issue.

Codeceptjs: I got ERROR webdriver: Request failed with status 404 due to unknown command when trying to click to an mobile element

When I tried to click an element using Appium and Codeceptjs, I got the error below:
ERROR webdriver: Request failed with status 404 due to unknown command: The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource.
Full log below:
-- FAILURES:
1) login
test something:
The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource
at getErrorFromResponseBody (C:\Users\DELL\node_modules\webdriver\build\utils.js:197:12)
at NodeJSRequest._request (C:\Users\DELL\node_modules\webdriver\build\request\index.js:158:60)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async Browser.wrapCommandFn (C:\Users\DELL\node_modules\#wdio\utils\build\shim.js:137:29)
Scenario Steps:
- I.click("//android.widget.Button[#content-desc="Login"]/android.widget.TextView[2]") at Test.<anonymous> (.\login_test.js:9:7)
- I.seeAppIsInstalled("com.wdiodemoapp") at Test.<anonymous> (.\login_test.js:8:7)
This error log appears when the codeceptjs call I.click() api I think. I tried use Accesibility ID and Xpath to get element but get the same error
My test code:
Feature('login');
const LOGIN_ICON = '~Login'
const LOGIN_BTN = '~button-LOGIN'
const EMAIL_TXT_FIELD = '~input-email'
const PASSWORD_TXT_FIELD = '~input-password'
Scenario('test something', ({ I }) => {
I.seeAppIsInstalled("com.wdiodemoapp")
I.click('//android.widget.Button[#content-desc="Login"]/android.widget.TextView[2]')
I.fillField(EMAIL_TXT_FIELD, "abc")
I.fillField(PASSWORD_TXT_FIELD, "12345678")
I.click(LOGIN_BTN)
});
Below are my config file:
exports.config = {
tests: './*_test.js',
output: './output',
helpers: {
Appium: {
platform: 'Android',
device: 'emulator',
desiredCapabilities: {
appPackage: "com.wdiodemoapp",
appActivity: "MainActivity",
deviceName: "emulator-5554",
platformName: "Android",
automationName: "UiAutomator2",
}
}
},
include: {
I: './steps_file.js'
},
bootstrap: null,
mocha: {},
name: 'codecept-mobile-auto'
}
Any idea please !!! I am the new to codeceptjs testing tool
Thank a lot
I had two things I had to do to fix this issue:
I needed the platform to be set to 'android' instead of 'Android'. It looks like codecept does a case sensitive check on whether to run the Touch click or Element click. If I'm reading the code right, you can see it in this line from their WebDriver.js file.
const clickMethod = this.browser.isMobile && this.browser.capabilities.platformName !== 'android' ? 'touchClick' : 'elementClick';
If you look through the Appium calls, this changes the API from /touch/click to /element/:elementid/click which works correctly.
Not sure if this was necessary, but I did run an npm update / npm install to refresh all of my packages. This was after updating to the latest version of appium.
Hope this helps and someone else doesn't have to beat their head against this wall.

Cannot make Cypress and Pact work together

I already have working project with few passing Cypress tests.
Now I'm trying to add contract tests using Cypress + Pact
In developer console I can see that app is calling /api/v1/document-service, but I get:
Pact verification failed - expected interactions did not match actual.
Part of logs:
W, [2021-07-20T12:49:37.157389 #34805] WARN -- : Verifying - actual interactions do not match expected interactions.
Missing requests:
POST /api/v1/document-service
W, [2021-07-20T12:49:37.157489 #34805] WARN -- : Missing requests:
POST /api/v1/document-service
I'm using:
cypress: 7.5.0
#pact-foundation/pact: 9.16.0
Steps I've done:
Added cypress plugin (https://github.com/pactflow/example-consumer-cypress/blob/master/cypress/plugins/cypress-pact.js)
Added commands (https://github.com/pactflow/example-consumer-cypress/blob/master/cypress/support/commands.js)
Added config to cypress.json (https://github.com/pactflow/example-consumer-cypress/blob/master/cypress.json) - not sure what to put to baseUrl, if I don't want interactions with real server.
Added test:
let server;
describe('Simple', () => {
before(() => {
cy.mockServer({
consumer: 'example-cypress-consumer',
provider: 'pactflow-example-provider',
}).then(opts => {
cy.log(opts)
server = opts
})
});
beforeEach(() => {
cy.fakeLogin()
cy.addMockRoute({
server,
as: 'products',
state: 'products exist',
uponReceiving: 'a request to all products',
withRequest: {
method: 'POST',
path: '/api/v1/document-service',
},
willRespondWith: {
status: 200,
body: {
data: {
collections: [
{
id: '954',
name: 'paystubs',
},
{
id: '1607',
name: 'mystubs',
},
],
},
},
},
});
});
it('is ok?', () => {
cy.visit('/new/experiments/FirstProject/collections');
});
})
Tried both using deprecated cy.server()/cy.route() and new cy.intercept(), but still verification failures.
At Pactflow, we've spent about 6 months using Cypress and Pact together, using the Pact mock service to generate pacts from our Cypress tests as suggested in https://pactflow.io/blog/cypress-pact-front-end-testing-with-confidence/
We have this week decided to change our approach, for the following reasons.
Our Cypress tests are much slower than our unit tests (15+ minutes), so generating the pact, and then getting it verified takes a lot longer when we generate the pact from our Cypress tests vs our unit tests.
Our Cypress tests can fail for reasons that are not to do with Pact (eg. layout changes, issues with the memory consumption on the build nodes, UI library upgrades etc) and this stops the pact from being generated.
The Cypress intercept() and mock service don't play very nicely together. Any request that does not have an explicit intercept() for Cypress ends up at the mock service, and every time a new endpoint is used by the page, the request hits the mock service, which then fails the overall test, even if that endpoint was not required for that specific test.
When a Cypress test fails, there is very good debugging provided by the Cypress library. When it fails for reasons to do with Pact, it's currently hard to identify the cause, because that information is not displayed in the browser (this could potentially be improved, however, it won't mitigate the already listed issues).
Our new approach is to generate our Pacts from our unit tests (instead of our Cypress tests) and to share the fixtures between the unit and Cypress tests, using a function that strips of the Pact matchers. eg.
const SOME_INTERACTION = {
state: 'some state',
uponReceiving: "some request",
withRequest: {
method: "GET",
path: "/something"
},
willRespondWith: {
status: 200,
body: {
something: like("hello")
}
}
}
Unit test
describe('Something', () => {
let someProviderMockService
beforeAll(() => {
someProviderMockService = new Pact({
consumer: 'some-consumer',
provider: 'some-provider'
})
return someProviderMockService.setup()
})
afterAll(() => someProviderMockService.finalize())
afterEach(() => someProviderMockService.verify())
describe('loadSomething', () => {
beforeEach(() => {
return someProviderMockService.addInteraction(SOME_INTERACTION)
})
it('returns something', async () => {
const something = await loadSomething()
//expectations here
})
})
})
Function that turns the Pact interaction format into Cypress route format, and strips out the Pact matchers.
const Matchers = require('#pact-foundation/pact-web').Matchers
// TODO map the request body and query parameters too
const toCypressInteraction = (interaction) => {
return {
method: interaction.withRequest.method,
url: Matchers.extractPayload(interaction.withRequest.path),
status: interaction.willRespondWith.status,
headers: Matchers.extractPayload(interaction.willRespondWith.headers),
response: Matchers.extractPayload(interaction.willRespondWith.body)
}
}
In the Cypress test
cy.route(toCypressInteraction(SOME_INTERACTION))
This approach has the following benefits:
The pact is generated quickly.
The pact is generated reliably.
The Cypress tests are more reliable and easier to debug.
The requests used in the Cypress tests are verified to be correct.
There is less chance of "interaction bloat", where interactions are added merely to test UI features, rather than because they provide valuable coverage.
I hope this information is helpful for you. We now recommend this approach over direct use of the mock service in Cypress tests.

How to load .wasm file in React-Native?

I have been trying to load a WebAssembly (.wasm) file - generated C++ code compiled to WebAssembly by Emscripten - in a React-Native app.
This is my code to fetch the .wasm file:
import fs from 'react-native-fs';
if (!global.WebAssembly) {
global.WebAssembly = require('webassemblyjs');
}
const fetchWasm = async () => {
const wasm = await fetch(`${fs.MainBundlePath}/calculator.wasm`);
console.log(wasm);
// Returns: Response {type: "default", status: 200, ok: true, statusText: undefined, headers: Headers, …}
const mod = await WebAssembly.instantiateStreaming(wasm);
console.log(mod);
// Throws: TypeError: Failed to execute 'compile' on 'WebAssembly': An argument must be provided, which must be a Response or Promise<Response> object
};
I tried everything in the Google search results I could find, but nothing worked so far. Unfortunately, the most related questions were unanswered.
Is there anyone who knows what I am doing wrong? Any help would be greatly appreciated!
There is one thing to be aware when wanting to load wasm :
Your webserver must report .wasm mime type as "application/wasm" , otherwise you won't be able loading it.
I assume still React-native JS runtime JSC still not support WebAssembly in Android build
the issue is still open
https://github.com/react-native-community/jsc-android-buildscripts/issues/113
Another way is to use Webview but I assume it is not you are expecting.
https://github.com/ExodusMovement/react-native-wasm

'window is not defined' when testing Paho MQTT Client with mocha and typescript

I googled for days but can't find anything about how to test the Paho MQTT Client. I tried it in a sort of naive way, like that:
import { suite, test, slow, timeout, skip, only } from 'mocha-typescript';
import chai = require('chai');
var jsdom = require('jsdom');
var Paho: any;
const expect: any = chai.expect;
const host: string = '127.0.0.1';
const port: number = 1384;
const clientId1: string = 'testid1';
const clientId2: string = 'testid2';
let client1;
let client2;
describe('test', function () {
it('should', function (done) {
// emulate browser window, which is required by Paho
jsdom.env("<html><body></body></html>", [],
function (err: any, window: any) {
// when window is ready, require Paho and
// initialize with built window
Paho = require('ng2-mqtt/mqttws31').jsdom(window);
// This does not work -> exception in mqttws31.js: window is not defined
client1 = new Paho.MQTT.Client(host, port, clientId1);
client1.connect({ onSuccess: () => { expect(true).to.be.true; done(); }, onFailure: () => { expect(false).to.be.true; } })
done();
});
});
});
However the Paho = require(...)-Part inside the callback function of jsdom.env(...) throws the exception in mqttws31.js: "window is not defined". Has anyone an idea how to solve that, in order to get the Paho Client running in a non-browser environment?
Thanks in advance!
https://www.npmjs.com/package/mochify You could be using similiar NPM module like this. Like you might expect Node.js environment dosen't have browser globals itself so use some library which can integrate these globals to your testing environment.
I am not very familiar with mocha but here's one more library I have played around in Karma as reference https://www.npmjs.com/package/karma-browserify
Or simply using some external service like BrowserStack https://www.npmjs.com/package/browserstack

Categories