Functional testing conditionals with Intern/Leadfoot - selenium

I am wishing to conditionally execute some commands/assertions depending on whether previous assertions succeeded or not.
I can't seem to find a way to nest then calls or conditionally execute things using the chaining syntax of leadfoot.
Here is my test (the returns at the end of each function is due to this being compiled coffeescript):
tdd.test(tableUrl, function() {
this.timeout = 60000;
return this.remote.get(require.toUrl("tests/pages/" + tableUrl))
.setPageLoadTimeout(60000)
.setFindTimeout(20000)
.findByCssSelector('.dataTables_wrapper table.dataTable')
.then(null, function(err) {
return assert.fail('', '', 'Table should exist');
}).then(pollUntil(function() {
var table;
table = document.querySelector('.dataTables_wrapper table.dataTable');
if (table.querySelectorAll('tbody td').length > 1) {
return true;
} else {
return null;
}
}, null, 20000, 500)).then(function() {
console.log('Assertion succeeded: Table should have data');
return assert.ok(true, 'Table should have data');
}, function(err) {
return assert.fail('', '', 'Table should have data');
});
});
When a table does not exist, both 'Table should exist' and 'Table should have data' assertions should be reported as failing. However, only the last assertion is failing. When I comment out the 'Table should have data' error callback, the 'Table should exist' assertion is reported as failing correctly.
What I would like to do is
test if a table exists (via findByCssSelector).
a) If it exists, report that it exists and test to see that it has more than one td element. This is currently done via pollUntil to ensure that the command is complete/promise is resolved as soon as more than one td is found instead of waiting for the whole implicit wait time.
b) If it does not exist, report that it does not exist.
I can't seem to find a way of not executing the error callback of the second 'Table should have data' poll if the first findByCssSelector fails, due to lack of conditionals and only the last assertion failure being reported in a test.

So conditional branching can happen with then calls, this answer addresses how to do conditional branching with intern.
The problem I was having was the pollUntil function not behaving the same way as a normal leadfoot Command method due to the function returning a callback function that returns a promise rather than a promise directly.
This can be circumvented by wrapping the pollUntil in an anonymous function, immediately calling the pollUntil function using the call method, passing in the current this value due to then setting the context of the callback to the Command object, and then finally chaining another Command.
This is what the above code turned into using correct conditional branching with pollUntil.
tdd.test(tableUrl, function() {
this.timeout = 60000;
return this.remote.get(require.toUrl("tests/pages/" + tableUrl))
.setPageLoadTimeout(60000)
.setFindTimeout(5000)
.findByCssSelector('.dataTables_wrapper table.dataTable')
.then((function() {
return pollUntil(function() {
var table;
table = document.querySelector('.dataTables_wrapper table.dataTable');
if (table.querySelectorAll('tbody td').length > 1) {
return true;
} else {
return null;
}
}, null, 20000, 500).call(this).then(function() {
console.log('Assertion succeeded: Table should have data');
return assert.ok(true, 'Table should have data');
}, function(err) {
return assert.fail('', '', 'Table should have data');
});
}), function(err) {
return assert.fail('', '', "Table should exist. Error: " + err.name);
});
});

Related

Run SQL Query in Phonegap

Hello everyone i am trying to run a query as follows, but i always get "SQL ERROR: undefined"
What am i doing wrong.
db = window.openDatabase("Database", "1.0", "SQLDB", 200000);
RunQuery ("DROP TABLE IF EXISTS ARTIGOS");
function RunQuery(QueryExecute) {
db.transaction(function(transaction){
transaction.executeSql(QueryExecute,successCB,errorCB);
})
}
function errorCB(err) {
alert("SQL Error: "+err.message);
}
function successCB() {
alert("SQL OK");
}
One possibility is that the transaction.executeSql method takes a parameters array as its second argument. So to use the callbacks like you have, you may have to pass in an empty array for the parameters. e.g.:
transaction.executeSql(QueryExecute, [], successCB, errorCB);
Referenced from the Cordova docs here:
https://cordova.apache.org/docs/en/latest/cordova/storage/storage.html

Calling multi-parameterized Azure SQL stored procedure from Nodejs

I am looking forward to know how can I run an Azure SQL stored procedure with multiple input parameters from Nodejs.
For example, if I have a stored procedure FIND_USERS(activity_status, color, gender) which runs a query
select * from users where isActive = activity_status and bay_color = color and userGender = gender;
I should be able to call this stored procedure from nodejs with the input parameters. The thing to understand here is that I want have a SQL transaction service that can take any CALL PROCEDURE type command along with the set of input parameters and call the procedure using those input parameters irrespective of the number of input parameters.
What I know is that for MySQL, there is a mysql library which lets me run procedures with multiple parameters. I have encapsulated it in MySQLConnector.js service as
var mysql = require('mysql');
exports.query = function(sql, values, next) {
if (arguments.length === 2) {
next = values;
values = null;
}
var connection = mysql.createConnection({
host:host,
user:user,
password:password,
database:database
});
connection.connect(function(err) {
if (err !== null) {
console.log("[MYSQL] Error connecting to mysql:" + err+'\n');
console.log(err == 'Error: ER_CON_COUNT_ERROR: Too many connections')
if(err == 'Error: ER_CON_COUNT_ERROR: Too many connections'){
connection.end();
}
}
});
connection.query(sql, values, function(err) {
connection.end();
if (err) {
throw err;
}
next.apply(this, arguments);
});
}
With this, I can call a stored procedure from nodejs with a function like
MySQLConnector.query('CALL FIND_USERS (?, ?, ?)', [1, 'blue', 'female'], function(err, userData) {
//do something with userData
});
How is it possible to do this for Azure MS SQL?
You can use tedious driver to connect to SQL Server. It supports both input+output parameter for statements and SPs, you can find the example in http://tediousjs.github.io/tedious/parameters.html
Feels free to raise an issue in GitHub if you need more assistance.
Make use of Edje.js and you should create a function and send the parameters when you call the function.
getHorarioFarmacia({pSede:'Sucursal Parrita'}, function (error, result){....
}
For more details, read the comments made by Luis Diego Pizarro here.

API returns array of JSON for only one result

Currently working on an API which given an address returns information about is. Some of the rows in our tables are duplicates, however being as there is over 15 million I cant go and find the duplicates. Instead I have opted to use
var query = `SELECT TOP 1 * from my_TABLE where..conditions`;
This ensures that only one row of the duplicates are returned.
The problem is when this is sent back as a JSON it comes as an array with one object.
In the Server.js file
// create Request object
var request = new sql.Request();
// query to the database
request.query(query, function (err, result) {
if (err) {
console.log("Error while querying database :- " + err);
res.send(err);
}
else {
res.send(result)
}
Returns this:
[{
Address:'our info'
}]
is there a way to have it respond with
{
Address:'our info'
}
Because from DB you've get list of object anyway, even there is only 1 item.
It works as you expected when you try to return json with the first element of your array.

Synchronous SQL queries in AngularJS

I have a 1.x AngularJS application, and need to perform 2 SQL queries synchronously (one after the other). The first does an update to a table, the second does a select against the same table to get the updated values. The problem I am encountering is that the queries are executed asynchronously, and occassionally the select is performed before the update completes, and I get back the "before" data rather than the "after" data. I put in a 500ms delay, and that works fine for me, but offshore folks with slower connections still encounter the problem intermittently. My code is below (simplified to make my point). Any thoughts as to how I can get the second query to wait until the first is complete?
$scope.saveUser = function(origuid, uid, name) {
$http.get('/ccrdb/updateAdmin?origuid=' + origuid + '&uid=' + uid + '&name=' + name);
setTimeout(function() {
$http.get('/ccrdb/getAdmins').then(function(response) {
$scope.users = response.data.detail;
});
return true;
}, 500);
};
$http returns promises that resolve when the request is done, so do:
$scope.saveUser = function(origuid, uid, name) {
$http.get('/ccrdb/updateAdmin?origuid=' + origuid + '&uid=' + uid + '&name=' + name)
.then(function() {
return $http.get('/ccrdb/getAdmins');
})
.then(function(response) {
$scope.users = response.data.detail;
});
};

How to do an "or" in chai should

How do I do an or test with chai.should?
e.g. something like
total.should.equal(4).or.equal(5)
or
total.should.equal.any(4,5)
What's the right syntax? I couldn't find anything in the documentation.
Asserts that the target is a member of the given array list. However, it’s often best to assert that the target is equal to its expected value.
expect(1).to.be.oneOf([1, 2, 3]);
expect(1).to.not.be.oneOf([2, 3, 4]);
https://www.chaijs.com/api/bdd/#method_oneof
Viewing the Chai expect / should documentation, there are several ways to do this test.
Note that you can chain using "and" but apparently not "or" - wish they had this functionality.
Check whether an object passes a truth test:
.satisfy(method)
#param{ Function }matcher
#param{ String }message_optional_
Asserts that the target passes a given truth test.
Example:
expect(1).to.satisfy(function(num) { return num > 0; });
In your case, to test an "or" condition:
yourVariable.should.satisfy(function (num) {
if ((num === 4) || (num === 5)) {
return true;
} else {
return false;
}
});
Check whether a number is within a range:
.within(start, finish)
#param{ Number }startlowerbound inclusive
#param{ Number }finishupperbound inclusive
#param{ String }message_optional_
Asserts that the target is within a range.
Example:
expect(7).to.be.within(5,10);
I have a similar problem to write tests to postman. I solved using the following script:
// delete all products, need token with admin role to complete this operation
pm.test("response is ok and should delete all products", function() {
pm.expect(pm.response.code).to.satisfy((status) => status === 204 || status === 404);
});
Here, I shared exactly what you need to check.
expect(true).to.satisfy(() => {
if (total == 4 || total == 5) return true;
else return false;
});
Because chai assertions throw error you could use try/catch construction:
try {
total.should.equal(4)
} catch (e) {
total.should.equal(5)
}
example of more difficult case:
try {
expect(result).to.have.nested.property('data.' + options.path, null)
} catch (e) {
expect(result).to.have.property('data', null)
}