How to call script include from the client script servicenow? - servicenow

Can anyone help me with how to call the script include from the client script?
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
//Current assignment group
var assignment_group = newValue;
if(assignment_group){
var coe = '';
var ga = new GlideAjax('sn_hr_core.scriptIncludeNameUtils'); //Script include
ga.addParam('sysparm_name','MethodName'); //Method/Function
ga.addParam('assignment_group',assignment_group); //Parameter
ga.getXMLAnswer(function(response){
coe = response;
if(coe){
g_form.setValue('u_hr_coe', coe);
}
});
}
}
Script Include:
MethodName: function (assignment_group) {
var sys_id = this.getParameter('assignment_group') ? this.getParameter('assignment_group') : assignment_group; //Params
var result = '';
if(sys_id){
var grSysChoice = new GlideRecord('sys_choice');
grSysChoice.addEncodedQuery("element=assignment_group^name=sn_hr_core_case^dependent_value="+sys_id);
grSysChoice.orderBy('sequence');
grSysChoice.setLimit(1);
grSysChoice.query();
if(grSysChoice.next()) {
result = grSysChoice.getValue('value');
}
}
return result;
},

We need to use GlideAjax to call script include from client script.
var ga = new GlideAjax('sn_hr_core.scriptIncludeNameUtils'); //Script include
ga.addParam('sysparm_name','MethodName'); //Method/Function
ga.addParam('assignment_group',assignment_group); //Parameter
ga.getXMLAnswer(function(response){
coe = response;
if(coe){
g_form.setValue('u_hr_coe', coe);
}
});
Youtube video for Ref:
https://youtu.be/zNGdVSCGggE

Related

Jasmine: Expected spy <function> to have been called error

In my angular application, I am trying to write a test case for following scenario but getting error 'Expected spy reinvite to have been called.'. Im testing on "jasmine-core: ^2.5.2 and "karma: ^1.3.0". I have written similar test cases and they passed without error.
In my controller file:
function reinvite() {
var emailsToReInvite = $j.map($scope.settingsData.userSettingsDetails, function(user) {
if(user.reInviteChecked){
return user.email;
}
});
if (emailsToReInvite.length >= 1) {
var invitation = { invitees: emailsToReInvite, listId: listId};
invitation = JSON.stringify(invitation);
inviteCollaboratorsModalDataService.reinvite(invitation).then(
function success(response) {
if(response.data.messages[0].code == 214){
$scope.showReinviteSuccess = true;
}
}else{
$scope.showReinviteSuccess = false;
}
}
);
}
}
And my spec file:
describe('settingsModalController', function() {
var controllerUnderTest = "settingsModalController";
var controllerResolver, rootScope, injector, $scope, inviteCollaboratorsModalDataService
beforeEach(function(){
angular.mock.module('sharedListApp');
inject(function($controller, $rootScope, $injector){
controllerResolver = $controller;
rootScope = $rootScope;
injector = $injector;
});
$scope = rootScope.$new();
inviteCollaboratorsModalDataService = injector.get('uiCommon.inviteCollaboratorsModalDataService');
});
it("should send re-invitation mail to selected users successfully", shouldReinviteSelectedUsers);
function shouldReinviteSelectedUsers() {
var $q = injector.get('$q');
$scope.settingsData = {
userSettingsDetails: [{email: 'abc#xyz.com'}]
};
var data = {
messages: [ { code: 214 }],
invite: {
invitation: $scope.settingsData
}
};
var response = { data: data };
var mockResult = new $q.defer();
mockResult.resolve(response);
spyOn(inviteCollaboratorsModalDataService, 'reinvite').and.returnValue(mockResult.promise);
controllerResolver(controllerUnderTest, { $scope: $scope });
$scope.reinvite();
$scope.showReinviteSuccess = true;
$scope.$apply();
expect(inviteCollaboratorsModalDataService.reinvite).toHaveBeenCalled();
expect($scope.showReinviteSuccess).toBe(true);
}
}
What am i doing wrong or what am i missing? Thanks in advance.
Ok, so i missed one variable to add in $scope.settingsData in my spec file which was why my spec code was not parsing into the first 'if' loop of the controller. Got it working by adding 'reInviteChecked: true' in:
$scope.settingsData = {
userSettingsDetails: [{email: 'abc#xyz.com', reInviteChecked: true}]
};

nightwatch assert ALL elements, not ANY

I'm trying to test that, when the Submit button is clicked on an empty form, all the "please fill in this field" labels are displayed.
I'm doing so with this:
page.click('#btn_submit');
page.expect.element('#validation_label_required').to.be.visible;
where #validation_label_required is represented by the CSS selector:
input[required] ~ p.error-message-required
However, this test passes if ANY of the validation labels are visible. The test should only pass if they ALL are.
How can I achieve this?
You will need to create a custom assertion for that where you locate all elements by selenium commands and then loop to verify condition. It should look something like this
var util = require('util');
exports.assertion = function (elementSelector, expectedValue, msg) {
this.message = msg || util.format('Testing if elements located by "%s" are visible', elementSelector);
this.expected = expectedValue;
this.pass = function (value) {
return value === this.expected;
};
this.value = function (result) {
return result;
};
this.command = function (callback) {
var that = this.api;
this.api.elements('css selector',elementSelector, function (elements) {
elements.value.forEach(function(element){
that.elementIdDisplayed(element.ELEMENT,function(result){
if(!result.value){
callback(false);
}
});
});
callback(true);
});
return this;
};
};
I've just ended up with another custom assertion that check how many elements are visible by given css selector.
/**
* Check how many elements are visible by given css selector.
*
*/
var util = require('util');
exports.assertion = function(elementSelector, expectedCount, msg) {
this.message = msg || util.format('Asserting %s elements located by css selector "%s" are visible', expectedCount, elementSelector);
this.expected = expectedCount;
this.count = 0;
this.pass = function(value) {
return value === this.expected;
};
this.value = function(result) {
return this.count;
};
this.command = function(callback) {
var me = this, elcount = 0;
this.count = 0;
this.api.elements('css selector', elementSelector, function(elements) {
if(elements.value && elements.value.length > 0){
elcount = elements.value.length;
}else{
return callback(false);
}
elements.value.forEach(function(element) {
me.api.elementIdDisplayed(element.ELEMENT, function(result) {
if (result.value) {
me.count++;
}
elcount--;
if (elcount === 0) {
callback(me.count);
}
});
});
});
};
};

How to make an ajax call asynchronous?

I was trying to retrieve CRM records using Ajax calls.
function RetrieveCrmRecords(entName, fields, filter, callback, orderby, errcallback) {
///<summary>
/// function to Retrieve Multiple CRM records.
///</summary>
//debugger;
var async = !!callback;
var setEntityName = entName + 'Set';
var _callback = callback;
filter = (filter) ? "&$filter=" + filter : '';
var query1 = CrmServerUrl + ODATA + "/";
var query2 = setEntityName + "()" + "?";
var queryUrl = query1 + query2;
if (fields != null) queryUrl += "$select=" + fields.join(',');
if (orderby != null) {
if (fields != null) {
queryUrl += '&';
}
queryUrl += "$orderby=" + orderby;
}
queryUrl += filter;
var performRequest = function (queryUrl, fnCallback) {
var async = !!fnCallback;
var opts = { url: queryUrl }
return _makeRequest(opts, async, function (data) {
var nextData = data.__next || null;
var resultsData = data.results || data;
var responseData = { 'results': resultsData, 'next': nextData }
if (nextData) {
responseData.LoadNext = function (callback) {
return performRequest(nextData, callback);
};
}
if (async) {
fnCallback(responseData);
}
else {
return responseData;
}
}, errcallback);
};
return performRequest(queryUrl, callback);
}
As I don't have that much idea about ajax calls, its hard to make this function Asynchronous for me.
Experts please help me to understand that this function is synchronous because of var async = !!callback; this?
If in place of this line I write var async=true; can it make this function asynchronous?
Thanks in advance.
I think i got you exactly what you are asking for.
Please don't get look into this file from where you have copied and pasted this function.
This will make you confuse if you are new for this.
Just call the function from your .js File like this.
function RetrieveCrmRecords(entName, fields, filter, calledForAsync, orderby, errcallback) {
//Your Code
}
function calledForAsync()
{
//Your Code
}
When Operation in RetrieveCrmRecords() will completed rest code will execute finely and then it will come into the calledForAsync().
This is called Async Call.
I hope you were asking for this.
Thanks,
Anish.

Not able to modify POST data in Firefox extension

I am trying to implement a Firefox Extension which modify the POST request data.
Code follows, it fails where marked "Fails here!!!"
Any insight would be helpful.
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
var newData = "test 123";
function LOG(msg) {
var consoleService = Components.classes["#mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService);
consoleService.logStringMessage(msg);
}
function CMP() {
this.registered = false;
this.register();
}
CMP.prototype = {
register: function() {
if (this.registered == false) {
var observerService = Components.classes["#mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.addObserver(this, "http-on-modify-request", false);
this.registered = true;
}
},
observe: function(subject, topic, data)
{
LOG("Inside observe");
if (topic == "http-on-modify-request")
{
LOG("TOPIC is http-on-modify-request");
var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
if(httpChannel.requestMethod == "POST"){
LOG("Inside POST")
var uploadChannel = httpChannel.QueryInterface(Components.interfaces.nsIUploadChannel);
//var uploadChannelStream = uploadChannel.uploadStream;
Modify the data here. Here for testing i am passing "test 123" as new data
var newStringInputStream = Components.classes['#mozilla.org/io/string-input-stream;1'].createInstance(Components.interfaces.nsIStringInputStream);
newStringInputStream.setData(newData,newData.length);
LOG("set data in newStringInputStream!!");
uploadChannel.setUploadStream(newStringInputStream, "text/plain", -1 );// Fails here!!!
httpChannel.requestMethod = "POST";
LOG("upload DONE!!")
}
}
},
QueryInterface : function(aIID) {
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsIObserver))
return this;
throw Components.results.NS_NOINTERFACE;
},
unregister: function() {
var observerService = Components.classes["#mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.removeObserver(this, "http-on-modify-request");
},
classID: Components.ID('{F799F47E-ABA5-4AF1-B8F2-BD74E3E5BCC0}'),
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIObserver])
};
if (XPCOMUtils.generateNSGetFactory)
{
var NSGetFactory = XPCOMUtils.generateNSGetFactory([CMP]);
}
Fixed it by changing by following in the above code. Main change was in setting modified data in httpChannel.uploadStream.
Hope this helps someone!
var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
if(httpChannel.requestMethod == "POST")
{
LOG("Inside POST")
var uploadChannel = httpChannel.QueryInterface(Components.interfaces.nsIUploadChannel);
var newStringInputStream = Components.classes['#mozilla.org/io/string-input-stream;1'].createInstance(Components.interfaces.nsIStringInputStream);
newStringInputStream.setData(newData,newData.length);
var uploadChannelStream = uploadChannel.uploadStream;
uploadChannelStream = uploadChannelStream.QueryInterface(Components.interfaces.nsISeekableStream).seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, 0);
httpChannel.uploadStream.QueryInterface(Components.interfaces.nsIMIMEInputStream);
httpChannel.uploadStream.setData(newStringInputStream);
LOG("Done POST")
}

Firefox, Mozilla validator error

I am getting this one error when I use the Mozilla validator:
This is the JS file:
const STATE_START = Components.interfaces.nsIWebProgressListener.STATE_START;
const STATE_STOP = Components.interfaces.nsIWebProgressListener.STATE_STOP;
// Version changes:
// It used to get the lists from a PHP file, but that was putting too much of a strain on the servers
// now it uses xml files.
// Randomizes the servers to load balance
// Mozilla editor suggested no synchronous file gets, so changed it to asynchronous
// Added one more server to help with the updates (Ilovemafiaafire.net)
// Edited some redirect code that some idiots were spreading FUD about.
var xmlDoc = null;
var quickFilter_100_count_redirect_url='http://www.mafiaafire.com/help_us.php';
var countXmlUrl = 0;
//var xmlUrl = 'http://elxotica.com/xml-update/xml-list.php';
var xmlUrl = new Array(4);
xmlUrl[0] = 'http://mafiaafire.com/xml-update/mf_xml_list.xml';
xmlUrl[1] = 'http://ifucksexygirls.com/xml-update/mf_xml_list.xml';
xmlUrl[2] = 'http://ezee.se/xml-update/mf_xml_list.xml';
xmlUrl[3] = 'http://ilovemafiaafire.net/mf_xml_list.xml';
xmlUrl.sort(function() {return 0.5 - Math.random()})
var realXmlUrl = xmlUrl[countXmlUrl];
var notificationUrl = 'http://mafiaafire.com/xml-update/click_here_for_details.php';
var root_node = null;
var second_node = null;
var timervar = null;
var mafiaafireFilterUrl = '';
//Calling the interface for preferences
var prefManager = Components.classes["#mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
var quickfilter_mafiaafire =
{
// get the domain name from the current url
get_domain_name:function()
{
var urlbar = window.content.location.href;
domain_name_parts = urlbar.match(/:\/\/(.[^/]+)/)[1].split('.');
if(domain_name_parts.length >= 3){
domain_name_parts[0] = '';
}
var dn = domain_name_parts.join('.');
if(dn.indexOf('.') == 0)
return dn.substr(1);
else
return dn;
},
// send ajax request to server for loading the xml
request_xml:function ()
{
//alert(countXmlUrl);
http_request = false;
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/xml');
}
if (!http_request)
{
return false;
}
http_request.onreadystatechange = this.response_xml;
http_request.open('GET', realXmlUrl, true);
http_request.send(null);
xmlDoc = http_request.responseXML;
},
// receive the ajax response
response_xml:function ()
{
if (http_request.readyState == 4)
{
if(http_request.status == 404 && countXmlUrl<=3)
{
countXmlUrl++;
//alert(xmlUrl[countXmlUrl]);
realXmlUrl = xmlUrl[countXmlUrl];
quickfilter_mafiaafire.request_xml();
}
if (http_request.status == 200)
{
xmlDoc = http_request.responseXML;
}
}
},
filterUrl:function()
{
var urlBar = window.content.location.href;
//check if url bar is blank or empty
if (urlBar == 'about:blank' || urlBar == '' || urlBar.indexOf('http')<0)
return false;
//1. get domain
processing_domain = this.get_domain_name();
//alert(processing_domain);
//Couldn't fetch the XML config, so returning gracefully
if(xmlDoc == null)
return false;
try
{
root_node = '';
// Parsing the xml
root_node = xmlDoc.getElementsByTagName('filter');
for(i=0;i<=root_node.length;i++)
{
second_node = '';
second_node = root_node[i];
if(second_node.getElementsByTagName('realdomain')[0].firstChild.nodeValue == processing_domain)
{
this.notificationBox();
mafiaafireFilterUrl = '';
mafiaafireFilterUrl = second_node.getElementsByTagName('filterdomain')[0].firstChild.nodeValue;
timervar = setTimeout("quickfilter_mafiaafire.redirectToAnotherUrl()",1500);
//window.content.location.href = second_node.getElementsByTagName('filterdomain')[0].firstChild.nodeValue;
//this.redirectToAnotherUrl(this.filterUrl);
//timervar = setInterval("quickfilter_mafiaafire.redirectToAnotherUrl(quickfilter_mafiaafire.filterUrl)",1000);
}
}
}
catch(e){
//alert(e.toString());
}
},
// This function is called for showing the notification
notificationBox:function()
{
try{
// Firefox default notification interface
var notificationBox = gBrowser.getNotificationBox();
notificationBox.removeAllNotifications(false);
notificationBox.appendNotification('You are being redirected', "", "chrome://quickfilter/content/filter.png", notificationBox.PRIORITY_INFO_HIGH, [{
accessKey: '',
label: ' click here for details',
callback: function() {
// Showing the notification Bar
window.content.location.href = notificationUrl;
}
}]);
}catch(e){}
},
redirectToAnotherUrl:function()
{
var qucikFilterRedirectCount = '';
//Read the value from preferrences
qucikFilterRedirectCount = prefManager.getCharPref("extensions.quickfilter_redirect_count");
//alert(qucikFilterRedirectCount);
if(qucikFilterRedirectCount % 15 == 0)
{
// Disable for now, can comment this entire section but this is the easier fix incase we decide to enable it later
//window.content.location.href = quickFilter_100_count_redirect_url+"?d="+mafiaafireFilterUrl;
window.content.location.href = mafiaafireFilterUrl;
}
else
{
window.content.location.href = mafiaafireFilterUrl;
}
qucikFilterRedirectCount = parseInt(qucikFilterRedirectCount)+1;
prefManager.setCharPref("extensions.quickfilter_redirect_count",qucikFilterRedirectCount);
}
}
var quickfilter_urlBarListener = {
QueryInterface: function(aIID)
{
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
},
//Called when the location of the window being watched changes
onLocationChange: function(aProgress, aRequest, aURI)
{
// This fires when the location bar changes; that is load event is confirmed
// or when the user switches tabs. If you use myListener for more than one tab/window,
// use aProgress.DOMWindow to obtain the tab/window which triggered the change.
quickfilter_mafiaafire.filterUrl();
},
//Notification indicating the state has changed for one of the requests associated with aWebProgress.
onStateChange: function(aProgress, aRequest, aFlag, aStatus)
{
if(aFlag & STATE_START)
{
// This fires when the load event is initiated
}
if(aFlag & STATE_STOP)
{
// This fires when the load finishes
}
},
//Notification that the progress has changed for one of the requests associated with aWebProgress
onProgressChange: function() {},
//Notification that the status of a request has changed. The status message is intended to be displayed to the user.
onStatusChange: function() {},
//Notification called for security progress
onSecurityChange: function() {},
onLinkIconAvailable: function() {}
};
var quickfilter_extension = {
init: function()
{
//Initiating the progressListerner
gBrowser.addProgressListener(quickfilter_urlBarListener, Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
//Load the block list xml form server
quickfilter_mafiaafire.request_xml();
},
uninit: function()
{
// Remove the progressListerner
gBrowser.removeProgressListener(quickfilter_urlBarListener);
}
};
// window.addEventListener("load", function () { TheGreatTest1.onFirefoxLoad(); }, false);
// this function is Called on window Onload event
window.addEventListener("load", function(e) {
quickfilter_extension.init();
}, false);
window.addEventListener("unload", function(e) {
quickfilter_extension.uninit();
}, false);
Can you tell me how to squash that error please?
It looks like the offending line is setTimeout("quickfilter_mafiaafire.redirectToAnotherUrl()",1500);
The setTimeout function can take a string (which then essentially gets eval'd) or a function (which gets called). Using a string is not recommended, for all the same reasons that using eval is not recommended. See https://developer.mozilla.org/en/DOM/window.setTimeout
In this case, the simplest fix would be to change it to setTimeout(function() { quickfilter_mafiaafire.redirectToAnotherUrl(); },1500);

Resources