I am running my intern test using the following code
node node_modules/intern/runner.js config=tests/intern
on my local machine. The application is using Dojo.
Basically I am trying to override the window.alert function as one of my test is failing because of unexpected alert.
window.alert = function(msg) {
//override alert function
//...
}
I tried putting this in my intern test and got the error. After some search I learned that window object is not available on node environment. Where can I override the alert?
The intern file looks like
define(['intern/lib/args'], function(args) {
var DEFAULT_PORT = "8080";
var urlInfo = {
PORT: args.port || DEFAULT_PORT,
BASE_URL : "http://localhost:".concat(args.port || DEFAULT_PORT, "/webtest"),
};
var config = {
proxyPort: 9000,
proxyUrl: 'http://localhost:9000',
capabilities: {
'selenium-version': '2.45.0',
},
...
...
};
return config;
});
Intern Test file example
define([
'intern!object',
'intern/chai!assert',
'intern/dojo/node!leadfoot/helpers/pollUntil',
'intern',
'intern/dojo/node!fs'
], function(registerSuite, assert, Pages, intern, fs) {
registerSuite ({
name: 'Tests',
setup: function() {
window.alert = function(msg){
console.log("Unexpected Alert: "+msg);
}
return this.remote.get(require.toUrl( intern.config.functionalInfo.BASE_URL)).maximizeWindow();
},
beforeEach: function() {
return
},
afterEach: function() {
return
},
'Test1' : function() {
this.timeout = 600000;
return this.remote
.setFindTimeout(5000)
....
},
}
window does not exist in node, you have to override its alert from code that runs on the browser (the code being tested), not on node itself. I would do it in the setup code for each test that uses it.
Related
I'm trying to use grunt-exec to run a javascript test runner with a deployed link variable passed in.
I am trying to do so by setting an environment variable grunt.option('link') using exec:setLink. In my test_runner.js I grab the variable with process.env.TEST_LINK. Unfortunately, it appears that grunt-exec won't run bash commands such as export(?)
Really, I don't care how the variable gets to my test_runner.js so any other ideas would be welcome.
exec: {
// DOESN'T WORK: Sets env variable with link for selenium tests
setLink: {
cmd: function () {
return "export TEST_LINK=" + "'" + grunt.option('link') + "'";
}
},
// Integration tests, needs TEST_LINK
selenium: {
cmd: function () {
return "node test/runner/jasmine_runner.js";
}
}
With grunt-exec, environment variables for the child process can be specified in the env option:
exec: {
selenium: {
cmd: function () {
return "node test/runner/jasmine_runner.js";
},
options: {
env: {
'TEST_LINK': grunt.option('link')
}
}
}
}
One thing to bear in mind is that if only TEST_LINK is specified in the env option, that will be the only environment variable for the child process. If you want the current process's environment variables to be passed, too, you can do something like this:
exec: {
selenium: {
cmd: function () {
return "node test/runner/jasmine_runner.js";
},
options: {
env: Object.assign({}, process.env, { 'TEST_LINK': grunt.option('link') })
}
}
}
I ended up just using node process.env['TEST_LINK'] = grunt.option('link');
Then retrieved in my javascript with process.env['TEST_LINK'];
How often do I need to set the setFindTimeout for my functional test?
When I execute the setFindTimeout,sometimes I need to put it in other test cases to change the findBy* method timeout.
-----------------Edit------------------------
What happen if I have multiple suite on different file.
For example I have start.js and admin.js
Is it your answer still valid for this case?
start.js
'use strict';
define([
'intern!object',
'intern/chai!assert',
'intern/dojo/node!fs'
], (registerSuite, assert, fs) => {
registerSuite(() => {
let testData;
let timeout;
let testCases;
testCases = {
name: 'Project Feature Test',
'Log into project': function() {
this.timeout = 60000 * 5;
return this.remote
.get(testData['site'])
.findByXpath('//a[#href="/saml-redirect"]').click().end()
.findById('userName').type(testData['username']).end()
.findById('password').type(testData['password']).end()
.findById('loginButton').click().end();
},
};
return testCases;
});
});
admin.js
'use strict';
define([
'intern!object',
'intern/chai!assert',
'intern/dojo/node!fs'
], (
registerSuite,
assert,
fs
) => {
registerSuite(() => {
testCases = {
name: 'Test Administration Page',
'Check User Functions': function() {
this.timeout = timeout * 3;
return this.remote
.sleep(3000)
.findByClassName('admin-button').click().end() //goto admin page
}
};
return testCases;
});
});
setFindTimeout sets the findBy timeout for a test session. Once you set it, the new timeout value persists through all the remaining tests in that session, or until it's changed by another call to setFindTimeout.
In my view, if you cannot control which file will run first, which will run after, then it's better to set in both files.
I often set it once in before of the top parent suite
This is error message on a protractor test use protractor http mock:
JavascriptError: javascript error: [$injector:nomod] Module 'httpMock'
is not available! You eit her misspelled the module name or forgot to
load it. If registering a module ensure that you specify the
dependencies as the second argument.
conf.js:
// An example configuration file.
exports.config = {
directConnect: true,
// Selenium server
SeleniumAddress: 'http://localhost:4444/wd/hub',
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
//baseUrl: 'http://develop.garbo.livebranches.com/sv-SE/',
//Framework to use. Jasmine 2 is recommended.
framework: 'jasmine2',
//frameworks: ['mocha', 'jasmine'],
// Spec patterns are relative to the current working directly when
// protractor is called.
//specs: ['testmain.js','testlogin.js'],
//specs: ['testmain.js','testteaPartyList.js','testpositionSearchIndex.js','testpositionList.js'],
specs: ['testlogin.js'],
//Options to be passed to Jasmine.
jasmineNodeOpts: {
defaultTimeoutInterval: 250000
},
mocks: {
dir: '../node_modules/protractor-http-mock',
//dir: 'mocks',
default: []
},
//=====login begin =====
onPrepare: function() {
require("protractor-http-mock").config = {
rootDirectory: '../node_modules/protractor-http-mock/lib',
//rootDirectory: __dirname,
protractorConfig: "conf.js", // name of the config here
};
}
//=====login end========
};
testlogin.js
describe('angularjs homepage', function() {
//browser.ignoreSynchronization = true;
it('should login', function() {
var mock = require('protractor-http-mock');
var todoList;
beforeEach(function() {
var url ='http://dev.etest.com:285/Actor/tbUsers/LoginAndGet';
var req = {Mobile:'14500000006',Password:'123456'};
var rep = {UserId:164,AccountId:328,Token:'328:dc91d536ab424aa0b8d7f1ecaf64c55b',Id:328};
mock([{
request: {
path: url,
method: 'POST',
data:req,
},
response: {
data: rep,
}
}]);
});
afterEach(function() {
mock.teardown();
});
browser.get('http://localhost:2024/daNiuJob/www/ionicWeb/index.html#/login');
console.log('mock='+mock);
element(by.model('data.userName')).sendKeys('14500000006');
element(by.model('data.password')).sendKeys('123456');
var btnlogin = element(by.id('Regist')).element(by.tagName('a'));
expect(browser.getTitle()).toEqual('userlogin');
browser.getTitle().then(function(text){
console.log('title='+text);
});
//cause mock error
expect(mock.requestsMade()).toEqual([
{ url : 'http://dev.etest.com:285/Actor/tbUsers/LoginAndGet', method : 'GET' },
]);
btnlogin.click();
browser.sleep(8000);
});
});
Why can't find httpMock, thank!
note:
C:\Users\HQ-XXX\AppData\Roaming\npm\node_modules\protractor\node_modules\protractor-http-mock
This is path of 'protractor-http-mock'
You should be giving the path of the http-mock module folder and not lib folder inside it. Change your rootDirectory path of protractor-http-mock inside onPrepare() function to -
rootDirectory: 'C:\Users\HQ-XXX\AppData\Roaming\npm\node_modules\protractor\node_modules\protractor-http-mock ',
If at all you need to provide a relative path then change it as below -
rootDirectory: '..\node_modules\protractor-http-mock ',
Hope this helps.
We had the same issue and it was related to the page reloading at the beginning of every spec.
This was caused by a faulty config of html5mode and the browser.get so it did a redirect at the beginning from foo.bar/ to foo.bar/#/ which unloads all injected protractor code.
I'm new at unit testing but I've tried many methods of getting my script (require module) loaded for use with my mocha test script. No matter what I do I always get undefined when I try to read a property or function or anything. Can anyone help point out what may be causing this?
rmq.js (script to test)
define(['bx_slider/1/bx_slider'], {
...
ansrTotal: 0,
...
init: function(settings) {
var self = this;
// do some stuff
return self;
}
});
test-bootstrap.js
require.config({
paths: {
'chai': '/node_modules/chai/chai',
'bx_slider/1/bx_slider': '/test/lib/bx_slider'
},
baseUrl: '/',
nodeRequire: require
});
mocha.setup({
ui: 'bdd'
});
require(['test/test'], function() {
if (window.mochaPhantomJS) {
mochaPhantomJS.run();
} else {
mocha.run();
}
});
test.js
define(['chai'], function(chai) {
var expect = chai.expect;
var rmq = require(['../src/js/rmq']);
describe('rmq test suite', function() {
before(function() {
return rmq.init();
});
it('should blah', function() {
expect(rmq.ansrTotal).to.equal(0);
});
});
});
If it helps, my directory structure is
.
/node_modules
/src
/js
rmq.js
/test
/lib
bx_slider.js
require.js
test-bootstrap.js
test.js
The exact error (for what I have currently written and posted here) in my CLI is
Testing: test/test.js
rmq test suite
"before all" hook
'undefined' is not a function (evaluating 'rmq.init()')
As Mathletics mentioned in a comment, you could do:
define(['chai', '../src/js/rmq'], function(chai, rmq) {
If, for some reason, you cannot do that, there's an alternative. (Maybe you simplified your code so much in your question that the reason is no longer apparent.)
define(['chai'], function(chai) {
var expect = chai.expect;
describe('rmq test suite', function() {
var rmq;
before(function (done) {
require(['../src/js/rmq'], function (_rmq) {
// Save the module we got to the `rmq` variable.
rmq = _rmq;
// Init and call `done` when finished.
rmq.init().then(done);
});
});
it('should blah', function() {
expect(rmq.ansrTotal).to.equal(0);
});
});
});
I have assumed that rmq.init() returns a promise since you did return rmq.init() in your code, and doing this does not make sense unless rmq.init() returns a promise. If that's not the case then you'd have to call rmq.init() and then call done() after it.
The code you had cannot work because require(['../src/js/rmq']) gets the module asynchronously so it does not return the module. You have to use it like I've shown above.
I'm trying to setup unit testing for my ext js application.
I'm using Jasmine 2.0 and PhantomJS to run the tests from console.
I can successfully init the store in the init method of the controller.
But, if I try to declare it in the stores config, I'm getting the following error :
TypeError: 'null' is not a constructor (evaluating 'new c()') (line 1) (1) ,
What is the cause for the error, and how can it be resolved?
Thank you in advance.
My code is below:
TestApplication.js
Ext.Loader.setConfig({ enabled: true });
Ext.ns('myApp');
// Loading different components like controller, model, view..
Ext.application({
name: 'myApp',
appFolder: '../App',
controllers: [],
autoCreateViewport: false,
init : function() {
myApp.app = this;
},
// Launch Jasmine test environment
launch: function () {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var htmlReporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter);
jasmineEnv.execute();
}
});
spec.js
describe("myController", function () {
var ctrl= null,
store = null;
beforeEach(function () {
bmTab = Ext.create("myApp.controller.myController");
bmTab.init();
});
});
myController.js
Ext.define('myApp.controller.myController', {
extend: 'Ext.app.Controller',
//stores: [Stores.myStore];
init:function() {
console.log('**** init');
var store = Ext.create(Stores.myStore);
console.log('**** store created' + store);
}
});
The problem was using Jasmine 2.0, when all of the tutorials were using Jasmine 1.3.
In Jasmine 2.0 a file boot.js was introduced.
And it was calling jasmine.getEnv().execute() on window.onload.
Because of that, specs were executing before Ext.launch was called.
Once I removed the call to execute() from the boot.js it all started working.
Below is a final version of my TestApplication.js code
P.S.
Note that, HtmlReporter is also initialized in the boot.js, so there is no need to init it on the Ext.launch function
Ext.Loader.setConfig({ enabled: true });
Ext.application({
name: 'myApp',
appFolder: '../App',
controllers: [],
autoCreateViewport: false,
// Launch Jasmine test environment
launch: function () {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
jasmineEnv.execute();
}
});