i am writing unit test cases for a js file which contains Progress Bar library, how to mock this
myjs.js
console.log("File that contains some js code....")
function myFunc(para1,para2){
var par = para1 + para2;
swal("Info",para);
return 3;
}
var bar = new ProgressBar.Line(dynamic, {//some code here} );
i am planning to unit test this function named "myFunc" so , i have written a test script that contains below code:
test.js
const $ = require('jquery');
global.$ = global.jQuery = $;
var ProgressBar = require('progressbar.js');
var myJs = require('myjs.js');
test('test if myFunc returns "3"',()=> {
expect(myJs.myFunc).toBe(3);
})
The myJs.js is loaded as a part of django template including the progressBar.js, while running this test case i get a error like ProgressBar is not defined.
additionally there exists a sweetalert in myFunc, how to mock this as well , a part from ProgressBar ?
Any kind help is appreciable
Related
I need to test some javascript I have in a php file (cannot be turned in any other extension file, for a few reasons, including it also contains php).
How can I achieve this using Jest?
For example, I have tried the following:
const parse = require('regenerator-runtime/runtime');
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
test("test JavaScript code in PHP file", async () => {
//create a mock of the DOM
const dom = new JSDOM(`<!DOCTYPE html><body>
<script>
// Add JS code from php file in here
let sum = function sum(a, b) {
return a + b
}
</script>
</body>`);
global.document = dom.window.document;
global.window = dom.window;
global.navigator = dom.window.navigator;
// run your tests here
expect(sum(1, 2)).toBe(3);
});
Unfortunately gives me an error:
ReferenceError: sum is not defined
How can I test the JS within the mock of the DOM since it is in it's own scope?
Is there a better way to test javascript in a php file?
I'm trying to get page objects to work for Protractor and Jasmine, and I'm getting "Failed: Cannot read property 'sendKeys' of undefined" when I try to use page objects.
I have read similar posts but they do not provide any answers for me or the situation is too different to be of any help to me.
I've checked every character of the two files. It appears that the test cannot see the page object file for some reason. BTW Protractor is installed Globally so I don't need to include it in the script.
Everything was working prior to converting to using the "test_page.js" file instead of the hard-coded values.
This is from a tutorial where his code was working fine.
/superhero-tests/test/test_spec.js file
//require() is a notjs function - https://nodejs.org/en/knowledge/getting-started/what-is-require/
const TestPage = require("../page-objects/test.page")
//This file runs the browser and executes the script.
describe('Super Hero Page',function(){
var testPage
//Jasmine: Before each test case, do something
beforeEach(function(){
testPage = new TestPage()
//Protractor: For non-angular sites
browser.ignoreSynchronization = true
//Open URL
browser.get('file:///C:/projects/Protractor/Superhero/index.html')
})
//Jasmine: After each test case, do something
afterEach(function(){
//Timer to prevent immediate closure of the window
//browser.sleep(5000)
})
it('should load the correct URL',function(){
//Enter text into form fields
testPage.emailFld.sendKeys('a#b.com')
testPage.passwordFld.sendKeys('Test.123')
//Check some text in an element
expect(testPage.loginTitleTxt.getText()).toEqual('Welcome. Please Log In.')
//Check a HTML element's attribute
expect( testPage.emailFld.getAttribute('value')).toEqual('a#b.com')
//Non-precise matching - don't use with an empty string, will pass
//expect( testPage.loginTitleTxt.getText() ).toContain('Welcome.')
})
})
/superhero-tests/page-objects/test_page.js file
var TestPage = function(){}
TestPage.prototype = Object.create({},{
emailFld: { get: function(){ return element( by.id('loginEmail') ) } }, //this is a page object
passswordFld: { get: function(){ return element( by.id('loginPassword') ) } }, //this is a page object
loginTitleTxt: { get: function(){ return element( by.id('login-title') ) } } //this is a page object
})
module.exports = TestPage
I don't know what kind of tutorial would overcomplicate the logic so much. Try this
/superhero-tests/page-objects/test_page.js file
module.exports = function() {
this.emailFld = element( by.id('loginEmail') )
this.passswordFld = element( by.id('loginPassword') )
this.loginTitleTxt = element( by.id('login-title') )
}
Also keep in mind, the tutorial teaches you to outdated syntax of protractor 3 or 4, which is no longer used since protractor 7 was released a few years ago
In the end I found alternative Page Object code which works (tutorial linked below):
The page object:
var TestPage = (function () {
function TestPage() {
this.emailFld = element( by.id('loginEmail') )
this.passswordFld = element( by.id('loginPassword') )
this.loginTitleTxt = element( by.id('login-title') )
}
return TestPage;
})();
module.exports = TestPage;
The spec(test) file:
//Test for Login page
var TestPage = require("../page-objects/test.page")
//Appears in command line
describe('Login page tests', function(){
var test = new TestPage();
//Executed before the tests
beforeEach(function(){
//Protractor: For non-angular sites
browser.ignoreSynchronization = true
//Open URL
browser.get('file:///C:/projects/Protractor/Superhero/index.html')
})
//Executed after the tests
afterEach(function(){
//Timer so we can see what is going on
//browser.sleep(5000)
})
//The test statements themselves
it('should display all the Login page elements',function(){
//With page object
expect( test.emailFld.getAttribute('placeholder') ).toEqual('Enter email')
})
})
It seems to make better use of the initial function and then do the module.exports at the end. The only other difference I can see is that they used var not const in the test file, but I don't know this would change much.
https://teamgaslight.com/blog/getting-started-with-protractor-and-page-objects-for-angularjs-e2e-testing
I need jest tests to fail if a jQuery selector returns 0. So if there is a typo, the test should fail.
Here's my index.js:
const sample = $('.someClass');
module.exports = sample;
This is how my index.test.js file looks like:
window.$ = window.jQuery = require('jquery');
const sample = require('./index');
test('test for selector', () => {
expect(sample.length).toBe(1);
});
If I run a console.log(sample.length), it returns 1 on browser console but always 0 on jest. Can someone please help me with this?
For now I managed to go around the problem as follows:
const sampleClassName = '.someClass';
const sample = $(sampleClassName); // For later usage
module.exports = sampleClassName;
And in the test file:
window.$ = window.jQuery = require('jquery');
const sampleClassName = require('./index');
test('test for selector', () => {
expect(someClassName).toBe('.someClass');
});
So this temporarily solves my problem but it would still be great to know if a better solution exists.
I want to prepend a JavaScript string to every module required in my code and compiled by Webpack.
For example, if my entry.js file looks like this:
import _ from 'lodash';
import $ from 'jquery';
import init from './init.js';
init();
I want my output.js bundle to consist of something like this:
function(module, exports, __webpack_require__) {
// prepended JavaScript goes here
// code for lodash module below
}
function(module, exports, __webpack_require__) {
// prepended JavaScript goes here
// code for jquery module below
}
function(module, exports, __webpack_require__) {
// prepended JavaScript goes here
// code for init.js module below
}
function(module, exports, __webpack_require__) {
// prepended JavaScript goes here
var _lodash = __webpack_require__(1);
var _jquery = __webpack_require__(2);
init();
}
I tried writing a simple loader, and it worked, except that it didn't include modules from node_modules since I'm excluding those from my /\.js$/ rule.
So I suspect I need to use a plugin. This is what I have so far:
var pluginName = "PrependJSPlugin";
var apply = (options, compiler) => {
compiler.hooks.compilation.tap(pluginName, compilation =>
compilation.hooks.afterOptimizeModules.tap(pluginName, modules => {
modules.forEach(mod => {
if (mod.resource !== void 0 && mod.resource.includes(".js")) {
var contId = "__WBP_PREPEND__";
var script = `
;var el = document.createElement('pre');
el.innerHTML = '${mod.resource}';
var container = document.getElementById('${contId}');
if (!container) {
container = document.createElement('div');
container.id = '${contId}';
container.appendChild(el);
document.getElementsByTagName('body')[0].appendChild(container);
} else {
container.appendChild(el);
}
`;
mod._source._value = script + mod._source._value;
}
});
})
);
};
module.exports = function(options) {
return {
apply: apply.bind(this, options)
};
};
For the most part, it seems like it's appending it correctly but the compiled output is getting corrupted somehow and I see syntax errors all over the place. I'm definitely doing something I shouldn't be doing with that _source property.
Can someone point me in the right direction?
Why do I want to do this?
This is not something that will go into production. I'm trying to debug a PhantomJS v1 error occurring in a third party service I use for rendering a PDF from an Angular page. Yikes, I know!
I'm catching errors with window.onerror and appending it to the body so they're displayed in the rendered PDF. Unfortunately, the errors don't include source file nor line numbers. So I'm trying to display the name of every module before it runs hoping to see at which one the JavaScript stops executing.
I was trying to create an end to end testing using Chimp. In front end there are few inputs(type=text) and my task was to set few values on that input field. Using webdriver.io i tried to select the id of inputs set there values by using setValue. but could not succeed.
Here is the code :
var assert = require('chai').expect;
var should = require('chai').should();
var webdriverio = require('webdriverio');
describe('Page title', function () {
it('should #watch', function () {
browser.url( 'http://localhost:3090/admin/createUser' );
browser.setValue( '#usernameInput', 'Seeking Wisdom' );
});
but nothing appeared in the input section. then i tried to do it with jquery :
import $ from "jquery";
var assert = require('chai').expect;
var should = require('chai').should();
var webdriverio = require('webdriverio'); var options = {}; var browser=webdriverio.remote(options)
describe('Page title', function () {
it('should #watch', function () {
browser.url( 'http://localhost:3090/admin/createUser' );
var selectBox = $('#usernameInput');
browser.setValue( 'selectBox', 'Seeking Wisdom' );
console.log(selectBox.getValue());
});
});
but still its not working and getting this error.
Error: jQuery requires a window with a document
at module.exports (node_modules/jquery/dist/jquery.js:31:12)
at Context.<anonymous> (tests/test.js:24:25)
at /home/shahin/.npm-packages/lib/node_modules/chimp/dist/lib/utils/fiberize.js:29:22
can anybody please tell me what really going on here?