Karate - Polyglot Exception using js callSingle() - karate

In the code presented below, I am trying to interact with a database through the use of a js function within the karate framework. The query used to get some data works as expected, likewise auxiliary information is accessible. The same function within the js file can be ran through groovy just fine but seems to explode when ran within karate.
JS Function to be ran in karate through a callSingle():
function() { let dbUser = Java.type('dev.dao.dbUser') return dbUser.getId(karate.properties['username'])
dbUser:
class dbUser {
static Integer getId(String email) {
db.sql.firstRow("select user_id from table.db_user where email = ?", [email]).userId
}
}
Karate-config.js
function fn() {
let config = {
project: karate.properties['vs.project'],
environment: karate.properties['vs.environment'],
baseUrl: karate.properties['vs.baseUrl'],
timeZoneId: karate.properties['vs.timeZoneId'],
env: karate.properties['vs.env'],
proxy: {
...
]
},
demoUserId: 1,
userId: karate.callSingle('classpath:proj/dev/js/dao/getDbUserId.js'),
createDBuid: karate.read('classpath:proj/dev/js/createDBuid.js'),
DBuid: karate.callonce('classpath:proj/dev/js/createDBuid.js')
}
}
Error returned calling the getDbUserId.js:
PolyglotError
<<<<
org.graalvm.polyglot.PolyglotException
com.intuit.karate.core.ScenarioBridge.callSingle(ScenarioBridge.java:243)
com.intuit.karate.core.ScenarioBridge.callSingle(ScenarioBridge.java:187)
.fn(Unnamed:18)

Related

Mocha unit testing mock variables in javascript

I am writing test cases for Javascript using mocha. My code exactly looks like this apigee
This javascript is deployed in apigee cloud. Where it has access to platform variables. This is myscript my-code.js
var responseCode = parseInt(context.getVariable(properties.source));
var log = {
org: context.getVariable(organization.name),
env: context.getVariable(environment.name),
responseCode: responseCode,
isError: (responseCode >= 400)
};
if (log.isError) {
log.errorMessage = context.getVariable(flow.error.message);
}
var logglyRequest = new Request(
'https://loggly.com/aaa',
'POST',
{'Content-Type': 'application/json'},
JSON.stringify(log)
);
httpClient.send(logglyRequest);
javascript code would have access to properties.source at run time. Apigee platform has its own internal way of how jc access those params. My question is if I am writing test case for this jc, how would I mock the values for properties.source. I am able to mock function call context.getVariable(). I am getting ReferenceError: properties is not defined. Test script in same in the apigee link given.
Try adding the following to your tests:
global.properties = {
source: 'jwt.Decode-IAM-JWT.decoded.header.kid'
};
That is what I do and it works fine.

Cannot run PlusDomains example in Google App Maker

I am trying to run this example code in Google App Maker:
/**
* The following example demonstrates how to create a post that is available
* to all users within your G Suite domain.
*/
function createPost() {
var userId = 'me';
var post = {
object: {
originalContent: 'Happy Monday! #caseofthemondays'
},
access: {
items: [{
type: 'domain'
}],
domainRestricted: true
}
};
post = PlusDomains.Activities.insert(post, userId);
Logger.log('Post created with URL: %s', post.url);
}
However, I keep getting this:
GoogleJsonResponseException: Access to the Google+ Domains API is not allowed as the user has consented to incompatible scopes.
Has anybody else managed to get this working?
Pavel's link had the answer: I just had to remove all access at https://security.google.com/settings/security/permissions and then re-authorize.
Thanks, Pavel!

JSON Store is not creating in Android for latest version fix pack 7.1.0.00.20160919-1656

Below sample code is not working in latest fix on Android but if we remove the password field from options then it's working fine. We are getting below error on Android but it's working fine on IOS
{"src":"initCollection","err":-3,"msg":"INVALID_KEY_ON_PROVISION","col":"people","usr":"test","doc":{},"res":{}}
function wlCommonInit(){
/*
* Use of WL.Client.connect() API before any connectivity to a MobileFirst Server is required.
* This API should be called only once, before any other WL.Client methods that communicate with the MobileFirst Server.
* Don't forget to specify and implement onSuccess and onFailure callback functions for WL.Client.connect(), e.g:
*
* WL.Client.connect({
* onSuccess: onConnectSuccess,
* onFailure: onConnectFailure
* });
*
*/
// Common initialization code goes here
}
function onClick(){
alert("Click");
var collectionName = 'people';
// Object that defines all the collections.
var collections = {
// Object that defines the 'people' collection.
people : {
// Object that defines the Search Fields for the 'people' collection.
searchFields : {name: 'string', age: 'integer'}
}
};
// Optional options object.
var options = {
username:"test",
// Optional password, default no passw`enter code here`ord.
password : '123',
};
WL.JSONStore.init(collections, options)
.then(function () {
alert("Success in jstore");
})
.fail(function (errorObject) {
// Handle failure for any of the previous JSONStore operations (init, add).
alert("Failure in jstore : "+ JSON.stringify(errorObject));
});
};
Update: The iFix is now released. Build number is 7.1.0.0-IF201610060540 .
This is a known issue with the latest available iFix. It has been recently fixed and should be available soon.
Keep an eye out for a newer iFix release in the IBM Fix Central website for a fix for this issue.

Reuse the browser session for Selenium WebDriver for Nightwatch.js tests

I need to write multiple tests (e.g. login test, use application once logged in tests, logout test, etc.) and need them all to be in separate files. The issue I run into is after each test, at the beginning of the next test being run, a new browser session start and it is no longer logged in due to the new session, so all my tests will fail except the login test.
So, is there a way to use the same browser session to run all of my tests sequentially without having to duplicate my login code? Sorry if this is a repost but I have searched and researched and not found any answers.
OR, is there a way to chain the test files somehow? Like having one file that you run that just calls all the other test files?
Using this function to chain together files:
extend = function(target) {
var sources = [].slice.call(arguments, 1);
sources.forEach(function (source) {
for (var prop in source) {
target[prop] = source[prop];
}
});
return target;
}
and adding files to this master file like this:
require("./testName.js");
module.exports = extend(module.exports,testName);
and having the test file look like this:
testName = {
"Test" : function(browser) {
browser
// Your test code
}
};
allowed me to have one file that could link all the tests to, and keep the same browser session the entire time. It runs the tests in the order you require them in the master file and if you do not call browser.end() until the last test is finished it will use one browser window for all tests.
Reuse of session is not good idea as you may run tests in different oreder, but
You could place login code into before function or even extract it into custom commands.
Example:
https://github.com/dimetron/backbone_app/blob/master/nightwatch/custom-commands/login.js
1 - In nightwatch config add
"custom_commands_path" : "nightwatch/custom-commands",
2 - Create custom-commands/login.js
exports.command = function(username, password, callback) {
var self = this;
this
.frame(null)
.waitForElementPresent('input[name=username]', 10000)
.setValue('input[name=username]', username)
.waitForElementPresent('input[name=password]', 10000)
.setValue('input[name=password]', password)
.click('#submit');
if( typeof callback === "function"){
callback.call(self);
}
return this; // allows the command to be chained.
};
3 - Test code - Before using .login(user, apssword)
module.exports = {
before: function(browser) {
console.log("Setting up...");
browser
.windowSize('current', 1024, 768)
.url("app:8000/")
.waitForElementVisible("body", 1000)
.login('user', 'password')
},
after : function(browser) {
browser.end()
console.log("Closing down...");
},
beforeEach: function(browser) {
browser
.pause(2000)
.useCss()
},
"Test 1": function(browser) {
browser
.assert.containsText("#div1", "some tex")
.pause(5000);
},
"Test 2": function(browser) {
browser
.assert.containsText("#div2", "some text")
.pause(5000);
}
}

grunt qunit in conjunction with grunt server

While running grunt server for developing, How can I separately use the grunt qunit task to run the tests.
While trying to pass ["test/**/*.html"] to the all property, but that fails to run and returns (Warning: 0/0 assertions ran (0ms) Use)
It looks like, it doesn't fire off a phantomjs instance and doesn't find these pates.
So I tried the following
grunt.initConfig({
....
qunit: {
all: {
options: {
urls: ['http://localhost:<%= connect.options.port %>/test/tests/foo.html']
}
}
}
....
});
It only works if when manually include all test html pages (like in the example).
The problem is
My Question is, can grunt qUnit work properly even while using grunt server.
And how can i have ["test/**/*.html"] syntax work correctly. I am sure there must be a better way this should work!
Also, how can use grunt.file.expand be utilized to programmatically add matching files to run in the grunt qunit task.
I've done something like this:
grunt.initConfig({
...
'qunit': {
'files': ['test/**/*.html']
}
...
});
...
// Wrap the qunit task
grunt.renameTask('qunit', 'contrib-qunit');
grunt.registerTask('qunit', function(host, protocol) {
host = host || 'localhost';
protocol = protocol || 'http';
// Turn qunit.files into urls for conrib-qunit
var urls = grunt.util._.map(grunt.file.expand(grunt.config.get('qunit.files')), function(file) {
return protocol + '://' + host + '/' + file;
});
var config = { 'options': { 'urls' : urls } };
grunt.config.set('contrib-qunit.all', config);
grunt.task.run('contrib-qunit');
});