Appium error handling doesn't work - javascript

I'm newbie in appium so may do something wrong.
I've got an issue with appium using wdio and jasmine
it('wtf', (done) => {
client.init().element('someName').getText()
// ^ here was a mistake
.then(result => result, err => {
// ^ this error handling wasn't work
throw new Error(`Cannot get text of element: #someName\n${err}`);
})
.then(text => expect(text).toBe('correct'))
.then(done)
});
appium server log told me:
[HTTP] --> POST /wd/hub/session/63aa60d2-9638-4b1a-a226-cfbb2fcfce2c/element {"using":"css selector","value":"someName"}
[debug] [MJSONWP] Calling AppiumDriver.findElement() with args: ["css selector","someName","63aa60d2-9638-4b1a-a226-cfbb2fcfce2c"]
[debug] [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator
[HTTP] <-- POST /wd/hub/session/63aa60d2-9638-4b1a-a226-cfbb2fcfce2c/element 500 4 ms - 152
[HTTP] --> POST /wd/hub/session {"desiredCapabilities":{"javascriptEnabled":true,"locationContextEnabled":true,"handlesAlerts":true,"rotatable":true,"platformName":"android","app":"./app-dev-debug.apk","appPackage":"com.#####.dev.debug","appActivity":"com.#####.feature.start.StartActivity","avdReadyTimeout":1000,"udid":"LGK350RGNBS4TS","deviceName":"LG-K350","clearSystemFiles":true,"fullReset":true,"newCommandTimeout":120,"requestOrigins":{"url":"http://webdriver.io","version":"4.12.0","name":"webdriverio"}}}
but jsmine stuck without throwed error, log:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Stack:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
at ontimeout (timers.js:475:11)
at tryOnTimeout (timers.js:310:5)
at Timer.listOnTimeout (timers.js:270:5)
'done' wasn't call in promise
configured jasmine timeout = 300000
main question: Why Jasmine don't receive the throwed exception?

found solution (dummy fix):
Use function:
testMobile = <T>(promise: Client<T>, done: () => void): Client<void> =>
promise.then(done, err => {
expect(err).toBe('Ok');
done();
});
and use:
it('wtf', done =>
testMobile(client.init()
.element('someName').getText()
.then(result => result, err => {
throw new Error(`Cannot get text of element: #someName\n${err}`);
})
.then(text => expect(text).toBe('correct')),
done)
};

Related

Firestore realtime listener error unhandled in node.js

I have made a function that I am exporting using node.js called return_match_uid. I am importing the function in another express routing file and am using async await, with try and catch to handle the error. But somehow, the errors produced by return_match_uid always slip and are unhandled, even though I am using the error handling for the realtime listener recommended by Firestore doc
Here is the function:
exports.return_match_uid = function return_match_uid() {
return new Promise((resolve, reject) => {
const unsub = db.collection('cities').onSnapshot(() => {
throw ("matching algo error");
resolve();
unsub();
}, err => {
console.log(err);
})
})
})
In another express router file, I am calling the function:
const Router = require('express').Router;
const router = new Router();
const {return_match_uid} = require("./match_algo");
router.get('/match', async (req, res) => {
try {
var match_user = await return_match_uid(req.query.data, req.query.rejected);
res.send(match_user);
}
catch (error) {
console.log("Matching algorithm return error: " + error);
}
})
The error I am throwing inside the function: matching algo error do not get caught by either the err => {console.log(err);}) in the function nor the try catch block in the router. It slips and causes my app to crash. It shows the following error:
throw "matching algo error!";
^
matching algo error!
(Use `node --trace-uncaught ...` to show where the exception was thrown)
[nodemon] app crashed - waiting for file changes before starting...
I am throwing an error inside matching algo error because I have some other codes in there, and there is a possibility that it produces an error. If it does, I would like to make sure that it gets handled properly.

Javascript Promises: testing error scenario

How do I test a promise that rejects with an error? (that is the expected behaviour)
I can not figure out why this test is failing. I'm catching the error rejected, and the test still fails. From the example provided at https://www.sitepoint.com/promises-in-javascript-unit-tests-the-definitive-guide/ this should work, and can't figure out how it's supposed to really. Both console logs appear.
it('shows that even an error occurs the test passes', (done) => {
const promise = new Promise((resolve, reject) => {
console.log('error promise is called');
setTimeout(() => {
reject(new Error('dummy error thrown'));
}, 100);
})
promise.then(() => {});
promise.catch((e) => {
console.log('error caught');
done();
});
});
1) promise behaviour in tests (async) - base test cases shows that even an error occurs the test passes:
Uncaught Error: dummy error thrown
at Timeout.setTimeout [as _onTimeout] (test\promise-spec.js:24:17)
Tried like this, still fail
promise
.then(() => {})
.catch((e) => {
console.log('error caught');
done();
});
Turns out it was because of a previous test that didn't call done, and it throwing an error killed this one

NodeJs express MongoDB with jest error while executing test case

Previous Question Link
Open Question
Scenario
I've trying to test if my route for GET endpoint work or not which I've set correctly and I've tested by running server. But my test case gives me following error
Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
I've searched a bit and have tried all possible solutions which are stated but it still gives me same error.
Code
const request = require ('supertest');
const app = require ('../../app');
const db = require ('../../db.js');
const url = process.env.MONGO_URI || 'mongodb://localhost:27017'
beforeAll (done => {
db.connect (url, err => {
if (err) {
console.log ('Unable to connect', err);
process.exit (1);
}else{
console.log('Succesfully connected')
}
});
});
afterAll (done => {
db.close ();
});
test ('should response the GET method',done => {
const res = request (app).get ('/expense');
return res
.then (json => {
console.log ("Length",json.body.length);
expect (json.body.length).toBe (1, done ());
})
.catch (err => {});
},10000);
Test Output
● Console
console.log test/express/startupTest.test.js:12
Succesfully connected
console.log test/express/startupTest.test.js:26
Length 1
● should response the GET method
Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
at pTimeout (node_modules/jest-jasmine2/build/queueRunner.js:53:21)
at Timeout.callback [as _onTimeout] (node_modules/jsdom/lib/jsdom/browser/Window.js:523:19)
at ontimeout (timers.js:469:11)
at tryOnTimeout (timers.js:304:5)
at Timer.listOnTimeout (timers.js:264:5)
Test Suites: 1 failed, 2 passed, 3 total
Tests: 1 failed, 6 passed, 7 total
Snapshots: 1 passed, 1 total
Time: 6.58s
You need to invoke done callback after establishing connection with the DB.
beforeAll (done => {
db.connect (url, err => {
if (err) {
console.log ('Unable to connect', err);
process.exit (1);
}else{
console.log('Succesfully connected');
done();
}
});
});
Same with afterAll:
afterAll (done => {
db.close (() => done());
});
Also, you don't need to use done callback in test case, since you are returning a promise:
test ('should response the GET method', () => {
const res = request (app).get ('/expense');
return res
.then (json => {
console.log ("Length",json.body.length);
expect (json.body.length).toBe (1);
})
.catch (err => {});
});
When you return a promise from a test case, test resolution will be delayed until the promise resolves.

Cloud Functions for Firebase - .once('value') returning nothing

I just started using Cloud Functions for Firebase. I'm stuck on retrieving data from the database.
I'm using .once('value') on a Firebase reference to convert it into a promise, but every time I run the function with Postman I get this error:
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:357:11)
at ServerResponse.header (/usr/lib/node_modules/firebase-tools/node_modules/express/lib/response.js:725:10)
at ServerResponse.send (/usr/lib/node_modules/firebase-tools/node_modules/express/lib/response.js:170:12)
at ServerResponse.json (/usr/lib/node_modules/firebase-tools/node_modules/express/lib/response.js:256:15)
at Timeout.req.functionTimeout.setTimeout [as _onTimeout] (/usr/lib/node_modules/firebase-tools/node_modules/#google-cloud/functions-emulator/src/supervisor/supervisor.js:192:14)
at ontimeout (timers.js:380:14)
at tryOnTimeout (timers.js:244:5)
at Timer.listOnTimeout (timers.js:214:5)
Here is the first function which calls for the function to get that data:
exports.userPlaylistStatus = functions.https.onRequest(async (request, response) => {
const userId = request.body.userId;
// Wait to get the user reference
const userRef = await buildUserRef(userId);
response.send(userRef);
});
Here is the function I'm using .once('value') in. The promise is never returning a value. Even when I put a console.log('hi') inside the .then(), it is never logged.
async function buildUserRef(_userId: string) {
return await admin.database().ref(`/users/${_userId}`).once('value').then(
// this would return the user reference but I have it as .val() for now
res => {return res.val();},
err => {console.log(err)}
);
}

Why is my jasmine test timing out before the DEFAULT_TIMEOUT_INTERVAL?

Related: Can't set timeout for jasmine
Jasmine 2.4.1
My test reports a failure due to timeout, even though the timeout value appears to be greater than the reported time.
I'm doing this:
describe('tests content controller', function(){
beforeAll(function(done) {
jasmine.DEFAULT_TIMEOUT_INTERVAL= 120000;
//...
})
fit('/content GET should return 200',function(done){
request(app)
.get('/content')
.set('Authorization', "bearer " + requestor.token)
.set('Accept', 'application/json')
.expect(200)
.end(function (err, res) {
console.log('timeout',jasmine.DEFAULT_TIMEOUT_INTERVAL); //prints 120000
if (err) done.fail(err);
expect(res.statusCode).toBe(200);
done();
})
});
Then this test fails, with:
1) tests content controller /content GET should return 200
Message:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Stack:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
Finished in 106.449 seconds
106.449 seconds is less than 120 seconds, which is what my timeout value appears to be set to.
So why is this test failing?
I wasn't calling done inside of my beforeAll, which caused this error.

Categories