How to mock dom element from karma testing - javascript

There is an input type file element. During angular file upload multiple times, the value is not being cleared. Hence manually clearing it using plain javascript dom manipulation.
Below is the code:
function removeFromQueue(item) {
vm.uploads.uploader.removeFromQueue(item);
// Clearing input file field for re-uploading
if(!vm.uploadFile) {
document.getElementById('upload-file-' + vm.type).value = null;
}
}
In this case, not able to mock the document.getElementById, hence controlling it using vm.uploadFile undefined variable from unit test case which is wrong. How to mock the dom element here?

You should be able to spyOn the document.getElementById and return the useful properties (i.e. value here). Like this,
spyOn(document, "getElementById").and.callFake(function() {
return {
value: 'test'
}
});
And then if you want, you can expect it to have been called,
expect(document.getElementById).toHaveBeenCalledWith('...')

Related

get a variable value from a method at runtime with frida

I'm completely beginner to frida.
I've this final method which belongs to class say X.
I want to extract the value of token variable -> result.getToken() when i hook frida to the android app which contains that class at runtime.
can anyone complete this code with javascript API of frida to get the value of token variable ?
Java.perform(function () {
Java.choose("com.xx.xx", {
onMatch: function (inst) {
//.................................
}
});
console.log("Done");
});
then i'll use --> frida -U -f "xxx.apk" -l test.js
thank you so much for help !!
Java.choose is in most cases the wrong approach because that only lists the existing instances of a class, so you can only hook a method if there is already an instance loaded into memory.
The common way is to hook the method itself so that all existing and newly created instances use your hook.
var classInstanceIdResult = Java.use('com.google.firebase.iid.InstanceIdResult');
var getTokenMethod = classInstanceIdResult.getToken.overload();
// replace the getToken() method with out own implementation
getTokenMethod.implementation = function () {
// call the orignal method
var ret = getTokenMethod.call(this);
// do something with ret
console.log("Token: " + ret);
return ret;
}
BTW: The code for hooking a Java method can simply be generated by using Jadx-Gui. Just decompile the APK, select the method and let Jadx generate the Frida code snipped necessary to hook the method (see context menu of the method).

Cypress how to store values yielded by a function into a variable

This has been bugging me from a long time. I am not well versed with javascript. Here it goes:
How do i store return value of a function into a variable:
lenValue = cy.get(selector).children().length
Above line of code returns undefined But when i try following in cypress test runner console then I get a valid output:
cy.$$(selector).children().length --> gives me correct number
How to return value from inside a then function and catch it to reuse later:
file1.js
function a(selector, attrName){
cy.get(selector).then(function ($el){
return $el.attr(attrName));
}
file2.js
state = file1Obj.a('#name','name')
What you're doing makes complete sense, but simply put, you cannot. (per the docs).
https://docs.cypress.io/guides/core-concepts/variables-and-aliases/#Return-Values
You can, however, use aliases to accomplish what (I think) you're after.
https://docs.cypress.io/guides/core-concepts/variables-and-aliases/#Aliases
#aeischeid shows you the wrong way to do it.
His code works only for a static site, but web pages are rarely static. As soon as API fetches are involved, lucky timing goes out the window and the test bombs.
This is why Cypress commands have automatic retry. Otherwise we could just build tests with jQuery.
Since cy.$$(selector).children().length --> gives me correct number, use that inside the helper function.
function a(selector, attrName) {
return cy.$$(selector).attr(attrName); // jQuery methods used
}
Or
function a(selector, attrName) {
return Cypress.$(selector).attr(attrName); // jQuery methods used
}
But be aware that jQuery only handles static pages, it does not retry if the attribute that you want to query arrives slowly.
For that use a command
cy.get('#name')
.should('have.attr', 'name') // retries until name exists
.then(name => { // guaranteed to have a value
// use name here
})
Here is a example from a cypress test I have that seems pretty relevant
let oldDescription;
cy.get('input#description').should(($input) => {
oldDescription = $input.val();
});
let randomDescription = Math.random().toString(36).substring(7);
cy.get('input#description').clear().type(randomDescription);
cy.get('input#description')
.parents('.ant-table-row')
.contains('Save').click();
cy.get('input#description').should('not.exist');
cy.contains(`${randomDescription}`);
cy.contains(`${oldDescription}`).should('not.exist');
because oldDescription is set inside of an asyncronous callback it isn't safe to expect it to be set, farther down the code outside of that callback, but in a lot of cases with cypress you end up having some other .get call or thing that waits, effectively pausing the code long enough that you can get away with not worrying about it.

Test immediately invoke function

I'm looking to create a test suite for a javascript file that contains an immediately invoked function. Eg.:
(function(context) {
context.setVariable("a") = context.getVariable("a") + 1
})(context);
I am not able to change the file to be tested.
My current attempt is using jest and the following:
context = null
test('test1', () => {
context = new context_mock();
context.setVariable("a", "1");
require("./My-Javascript");
// Check result
helper.check(context.getVariable("a"), 2);
});
test('test2', () => {
context = new context_mock();
context.setVariable("a", "2");
require("./My-Javascript");
// Check result
helper.check(context.getVariable("a"), 3);
});
In this case, test 2 always fails. I assume it's because the javascript file can't be required twice.
Edit: Yes context is a global variable that is operated on when the script is required. I'm aware this is an ugly solution but I'm unable to change the original file.
Any suggestions are appreciated.
jest has an extra level of caching the modules which is preventing the require from running multiple times.
Adding the following to clear the modules cache prior to calls allows the script to run multiple times:
beforeEach(() => {
jest.resetModules()
});

JavaScript Revealing Module pattern private variable state

I have recently started working on a JavaScript project and coming from Java world things seem, not surprisingly, weird at times.
I was implementing a simple module (Using revealing module pattern, afaik) which would provide config based on initialisation but notice that after a "local" variable domain is assigned in init() function its value differs depending whether it is accessed via a "getter" function getDomain() or directly via domain variable as exposed via modules "public" API.
See the following stripped down code which demonstrates the issue.
var ConfigManager = (function() {
var privateDomain = 'default';
function init(dom) {
privateDomain = dom;
}
function getDomain() {
return privateDomain;
}
return {
init: init,
domain: privateDomain,
getDomain: getDomain
};
})();
console.log(ConfigManager.domain); // Prints 'default'
console.log(ConfigManager.getDomain()); // Prints 'default'
ConfigManager.init('new domain');
console.log(ConfigManager.domain); // Prints 'default' <-- What??
console.log(ConfigManager.getDomain()); // Prints 'new domain'
At this point I am very confused how a variable returned from a getter function can have a different value when it is accessed directly?
Than you in advance!
Since privateDomain is a String, you're not copying / returning the reference, but the value.
Therefore when you're changing the domain using the init function, it just updates privateDomain, since domain has no link to it other than being a copy.
Hope it helps! :)
It's because when domain is returned, it's value is still "default". It's how Javascript works, more info here: Javascript by reference vs. by value
But when you use the function "getDomain" you will get the updated value.
Also have a look at the get/set syntax: Getter

How to unit test a jQuery selector?

Just a quick question... I currently have the following jQuery code with a selector in it.
var ID = "idControl"
function doesTreeViewExist()
{
if($('#' + ID).length == 0)
{
return false;
}
else
{
return true;
}
}
I was wondering how do I write the test to test the selector using QUnit? More specifically, I'm having trouble coming up with the syntax/code.
EDIT:
Ok, suppose now I want to mock the selector call instead because I cannot get access to the actual website. I'm using JsTestDriver as my testing tool, which means I cannot touch the browser the tests are running in (else the test runs will stop). What about in such situation? How can I possibly test the code?
Thanks.
The function you post, can be heavily simplified:
var ID = "idControl";
function doesTreeViewExist() {
return !!$('#' + ID).length;
}
Using the !! construct (double bitwise NOT), to convert the length property to Boolean, it will return false only when length is zero.
Speaking about qUnit, you can easily setup a simple test like this:
test("Your selector test", function() {
ok($('#idControl').length > 0, "idControl exists");
// or simply
ok($('#idControl').length, "idControl exists");
});
The ok function does a boolean assertion, equivalent to JUnit's assertTrue.
I test selectors manually, then pass them to code that uses them. I can then unit test the code that uses them. If you want to just test a selector, you need access to the HTML it affects. Your test could include HTML to target, something like:
test("selector works", function() {
var html = $('<input type="select"><option value=0/></input');
var result = $('option', html);
ok(result.count() == 1);
});
But I don't do that... I put my selectors at the edge of the code so I can get to them quickly and step through them under the debugger. I'll have a simple class whose properties are those selectors. Then I'll mock/stub that simple class, so I can write code for everything dependent on those selectors.
The reason I don't test my selectors is because the HTML they target is generated by ASP.NET code, and hard to get to from a javascript test. But I can wrap them in a Humble Object ("http://xunitpatterns.com/Humble Object.html") then test code that depends on that humble object. Here's a simple wrapper class that I can replace with test doubles:
var createSelectWidget = function(rootSelector)
{
return {
userText : $('span', rootSelector),
inputList : $('option', rootSelector),
};
}
Whatever dependency injection pattern you use, you can then stub it like below. Suppose my widget has a select input to read the value of, and a span I want to write some results to:
var createSelectWidgetStub = function()
{
return {
userText : { text = function() {}},
inputList : { val = function() {}},
};
}
I can then pass around this stub in tests where I want to isolate the dependency but don't care about interactions with that dependency. When I want to verify interactions with the dependency, I can mock it with JSMock. Suppose I want to verify interactions with the input list, I would prepare a stub with the one element mock'd:
var selectMock = createSelectWidgetStub();
selectMock.inputList = mc.createMock(selectMock.inputList);
I used Jack and successfully mocked the jquery call and returned a custom length and expected result.
Something like:
jack (function() {
jack.expect("$").exactly("1").withArguments("#" + ID).returnValue( {length:0} );
doesTreeViewExist()
assertEquals(false, result);
});
I have also managed to supply a DOM structure to satisfy the jquery call, as I'm using one of JsTestDriver's built-in function HtmlDoc. Something like:
/*:DOC += <span id="idControl"></span> */
or simply create a DOM sturcture without the specified id to get the false statement.
HTH.

Categories

Resources