how do I write jasmine test for innerHTML element - jasmine

so my code does this...
diff = timevalue - (((Date.now() - startDate)/1000)|0);
document.getElementById("timer").innerHTML = diff.toLocaleString();
part of my current test looks like this...
it("count should define tictoc", function(){
jasmine.clock().install();
aTimer.count(25);
jasmine.clock().tick(1002);
expect(aTimer.tictoc).toEqual(1);
expect(document.getElementById("timer").innerHtml).toBe("success");
jasmine.clock().uninstall();
});
but I am getting this back from jasmine...
"TypeError: Cannot set property 'innerHTML' of null"
now I think this is because the html element is not present....which makes sense since I'm testing....but how do I mock that element so my test works?

I just got it:
it("count should define tictoc", function(){
jasmine.clock().install();
var dummyElement = document.createElement('span');
document.getElementById = jasmine.createSpy('HTML Element').and.returnValue(dummyElement);
aTimer.count(25);
jasmine.clock().tick(1002);
expect(aTimer.tictoc).toEqual(1);
expect(document.getElementById("timer").innerHTML).toEqual('25');
jasmine.clock().uninstall();
});

Related

Nightwatch .execute() how to pass parameter to execute function, is it possible?

Please be patient - I am a beginner in programming. Tester for long time but programming is not my domain.
My test is:
from the backend I get some list with some element (e.g. 5 text strings)
I click some element on page which displayed those 5 elements (of course I don't know if listed elements are correct or not)
I need to check if list of elements displayed on ui is the list received from backend
Problem:
I cannot access the elements by Nightwatch api css selector, at least I could not manage (Angular app) to do it with Nightwatch
I found I could do it with .execute()
My code is (failing):
browser
.click(selector.HEADER.APPS_GRID, function () {
for (var app in appsList) {
let appShortName = appsList[app].shortName
let appLongName = appsList[app].longName
let appUrl = appsList[app].url
let appVisibility = appsList[app].visibility
browser.execute(function(app){
var appShortNameDisplayed = document.getElementsByClassName('logo-as-text')[app].innerText
var appLongNameDisplayed = document.getElementsByClassName('app-name')[app].innerText
return [appShortNameDisplayed, appLongNameDisplayed]
}, function(result){
console.log(result.value[0])
})
}
})
It fails in lines:
var appShortNameDisplayed = document.getElementsByClassName('logo-as-text')[app].innerText
var appLongNameDisplayed = document.getElementsByClassName('app-name')[app].innerText
unfortunately I have to make query with [app] - iterating by elements of object. If I skip [app].innerText I get some data like element-6066-11e4-a52e-4f735466cecf instead of text values displayed on page
I get error:
Error while running .executeScript() protocol action: TypeError: document.getElementsByClassName(...)[app] is undefined
Is it possible to pass the "app" param (counter) to the document query?
Or is it the way I have to make one query that will return as many data as necessary and then handle data returned in this block
function(result) {
console.log(result.value[0])
})
The fragment of html page is
<div _ngcontent-c8="" class="ep-app-icon mt-auto mb-auto text-center logo-as-text"> XXX </div>
... and I need to get this "XXX" text.
As your own comment suggests, there is an args argument to .execute that is an array. The array elements will be the arguments in the function passed to execute.
See https://nightwatchjs.org/api/commands/#execute
.executeAsync(function(){
var buttons=document.getElementsByTagName('button');
buttons[2].click();
return buttons;
},[],function(result){
console.log('done')
})
Try Async it works for sure

Sinon JQuery selectors mock

I am trying to test a function using mocha/sinonjs. The function I want to test is responsible for showing or hiding some element in my DOM.
This is my function
var updateUI = function() {
$('#login').show();
$('#logout').hide();
};
I tried to mock using sinon but I'm not sure if it is possible or the correct thing to do in this case.
This is what I have tried but I keep getting an error "TypeError: undefined is not a function" during the expect call
var mockLogin = sinon.mock($);
mockLogin.withArgs('#login').expects("show").once();
I simple want to test my 2 jquery calls have been called. I tried to use spies but continue to get exceptions
Looking further into the sinon doc I found that the following worked for me.
var jQueryShow = sinon.stub($.fn, 'show');
var jQueryHide = sinon.stub($.fn, 'hide');
jQueryShow.callCount.should.be.equal(1);
jQueryShow.thisValues[0].selector.should.be.equal("#login");
jQueryHide.callCount.should.be.equal(1);
jQueryHide.thisValues[0].selector.should.be.equal("#logout");
I'm not sure if there an easier way but it checks for the selectors I need

Server handler event info parameters google apps script

A simple app:
function doGet() {
return(test());
}
function test(){
var smiley = UiApp.createApplication().setTitle("TT Bomgar Feedback");
var textIn = smiley.createTextBox().setName("text");
var textOut = smiley.createLabel().setId("label").setVisible(false);
var button = smiley.createSubmitButton("Submit");
var handler = smiley.createServerHandler("handler");
button.addClickHandler(handler);
smiley.add(button);
smiley.add(textIn);
smiley.add(textOut);
return(smiley);
}
function handler(e){
app = UiApp.getActiveApplication();
var text = e.parameter.text;
app.getElementById("label").setVisible(true).setText(text);
return(app);
}
In the handler function, var text is always undefined. This means that the following is returned:
So, undefined is printed instead of "some text".
I don't understand why though, because I have correctly set the name of the text box element in the test function ...
Any assistance is greatly appreciated.
You need to add a callBackElemnt to the handler so that its value will get passed to the handler function. In normal practice, we just add the top most element containing all other elements. But you can also add all the elements whose value you want to pass.
modified script
var handler = smiley.createServerHandler("handler");
handler.addCallbackElement(textIn);
button.addClickHandler(handler);
You have to add callback element to your server handler:
...
var handler = smiley.createServerHandler("handler");
handler.addCallbackElement(textIn);
button.addClickHandler(handler);
...
https://developers.google.com/apps-script/class_serverhandler#addCallbackElement

Grails remoteLink

I'm trying to make a call to the server with Ajax using Grails remoteLink. The code is the following:
<g:remoteLink controller="event" action="recommend" id="1" onSuccess="recommend(e)" params="[artist:searchedArtist]">
Recommend
</g:remoteLink>
The controller is:
def recommend = {
.
.
.
def jsonList = [artist: "${params.artist}",
location: [
lat:"53.872715",
lng:"-1.372895"]
]
render jsonList as JSON
}
and the javascript function is:
function recommend(response){
var recommendedResults = eval('(' + response.responseText + ')');
var point = new google.maps.LatLng(${recommendedResults.location.lat}, ${recommendedResults.location.lng});
var myMarkerOptions = {
position: point,
map: map
};
var marker = new google.maps.Marker(myMarkerOptions);
}
My problem is that the recommend() javascript function is never being called.
Any thoughts? Thanks very much.
UPDATE
I just noticed that the line:
var point = new google.maps.LatLng(${recommendedResults.location.lat}, ${recommendedResults.location.lng});
was not right. So just for debugging purposes, I tried with the "recommend()" javascript function like this:
function recommend(response){
alert.window("Foo");
}
and still doesn't work. The alert never pops up.
The code fragment of the remoteLink which appears in the html source is:
Recommend
I found out that the problem was not with the Ajax. It was a mistake in the Javascript function. I was calling alert.window() instead of window.alert().
Thanks for the Firebug tip Gregg.
I understand your problem completely,
Please change your code to :
< g:remoteLink controller="event" action="recommend" id="1" onSuccess="recommend(data)" params="[artist:searchedArtist]">
Recommend
</g:remoteLink>
you must pass data in onSuccess and onFailure function grails only understand it.

jQuery plugin that accepts and returns value using val() method

Does anyone knows how to create a jQuery plugin that will react to the call to val() method?
Here's the scenario:
Take a set of DIVs using jQuery selector and apply a plugin on them (let's say the plugin is called "mytest".
Using the val() method on the same set of DIVs I'd like to set them some properties.
What's the proper way to do this sort of things?
$.fn.example = function(options) {
return this.each(function() {
var edits = $("<input type='text'/><input type='text' />");
$(this).html(edits);
});
}
$(document).ready(function() {
$("#example").example();
$("#example").val("value1 value2");
window.alert($("#example").val());
});
In this case the first edit should have the value "value1" and the second edit the value "value2". And v.v. by calling the "val()" method I'd like to get the string "value1 value2" back.
Best regards,
Matthias
I've realized that by using additional methods and then calling them using
$("...").pluginname("methodname", ..parameters..);
syntax. It works exactly like other plugins so I guess that's the right way to go.
In the case of the example above the code would look like this:
$.widget("ui.example", {
_init: function() {
}
});
$.extend($.ui.example, {
version: "1.7.1",
defaults: {
value: ""
}
});
And then the usage would be:
$("#example").example("option", "value", "value1 value2");
var value = $("#example").example("option", "value");
window.alert(value);

Resources