Reading functions from one file to another in protractor JS - javascript

I have written a file with a number of functions that I wish to use across a variety of E2E tests. I have been trying to test this out and have found some solutions but none work for me.
This is how things stand.
In my TestingFunc.js file I have created the following:
var TestingFunc = function() {
this.login = function(Url) {
browser.ignoreSynchronization = true;
browser.get(Url);
browser.wait(EC.elementToBeClickable(element(by.eeHook('login',null,null))), 300000);
element(by.eeHook('login', null, null)).click();
element(by.eeHook('authenticationEmailField',null,null)).sendKeys(logins.International);
element(by.name('password')).sendKeys(logins.password);
element(by.eeHook('authenticationLoginButton',null,null)).click();
browser.wait(EC.elementToBeClickable(paymentFlow), 100000);
paymentFlow.click();
browser.wait(EC.elementToBeClickable(depositAmount), 7000);
};
};
and I am trying to read it in the following:
var url = 'http://master.mrgreen.avengers.zone/en-US/casino';
var TestingFunc = require("C:/Users/davbor.3DB/MrGreen Google Drive/LetsTest/TestingFunc.js");
describe("The security application", function () {
var test = new TestingFunc();
it("will login to the page", function () {
test.login(url);
});
});
Yet each time I run it I keep getting the error:
Failures:
1) The security application encountered a declaration exception
Message:
TypeError: TestingFunc is not a constructor
Stack:
TypeError: TestingFunc is not a constructor
at Suite.<anonymous> (C:\Users\davbor.3DB\MrGreen Google Drive\LetsTest\Testing.js:6:17)
Not sure what i am missing as I have even asked an in house developer to look at it without success.

var TestingFunc = require("C:/Users/davbor.3DB/MrGreen Google Drive/LetsTest/TestingFunc.js");
1) You should not use full path. Use relative path to this file.
In your Testing.js require should look like this:
var TestingFunc = require("./TestingFunc.js");
2) You should 'export' your function:
var TestingFunc = function() {
this.login = function(Url) {
browser.ignoreSynchronization = true;
browser.get(Url);
browser.wait(EC.elementToBeClickable(element(by.eeHook('login',null,null))), 300000);
element(by.eeHook('login', null, null)).click();
element(by.eeHook('authenticationEmailField',null,null)).sendKeys(logins.International);
element(by.name('password')).sendKeys(logins.password);
element(by.eeHook('authenticationLoginButton',null,null)).click();
browser.wait(EC.elementToBeClickable(paymentFlow), 100000);
paymentFlow.click();
browser.wait(EC.elementToBeClickable(depositAmount), 7000);
};
};
module.exports = TestingFunc;
Check more about nodejs modules here:
https://nodejs.org/api/modules.html

Related

Loading multiple files with require statement on JS

The execution returns the following error when trying to load multiple js:
TypeError: Cannot read property 'get' of undefined
The solution that I am implementing has a login_steps.js:
var LoginSteps = function() {
var LoginSteps = require("../pages/pages.js");
browser.ignoreSynchronization = true;
this.World = function MyWorld() {
this.page = new LoginSteps();
};
this.Given(/^the page is open$/, function (callback) {
this.page.login_page.get();
callback();
});
};
module.exports = LoginSteps;
A page.js where I want to include all the modules that I need.
var Pages = function() {
module.exports = {
shipments_page: require('./shipments_page.js'),
login_page: require('./login_page.js'),
};
};
module.exports = Pages;
And the modules login_page.js:
var chai = require('chai').use(require('chai-as-promised'));
var expect = chai.expect;
this.get = function() {
browser.get('https://aaa/login');
};
this.setEmail = function(value) {
element(by.id('login-email')).sendKeys(value);
};
this.setPassword = function(value) {
element(by.id('login-password')).sendKeys(value);
};
this.clickAccede = function() {
element(by.id('login-submit')).click()
};
shipment_page.js:
var chai = require('chai').use(require('chai-as-promised'));
var expect = chai.expect;
this.pageIsLoaded = function() {
browser.waitForAngular();
expect(browser.getTitle()).to.be.eventually.equals('title');
};
Then when I execute the test the log shows
Failures:
1) Scenario: User login - features/login.feature:3
Step: Given the page is open - features/login.feature:4
Step Definition: features/steps/login_steps.js:16
Message:
TypeError: Cannot read property 'get' of undefined
at MyWorld.<anonymous> (/Users/mj/IdeaProjects/atpro/features/steps/login_steps.js:17:30)
at process._tickCallback (internal/process/next_tick.js:61:11)
1 scenario (1 failed)
5 steps (1 failed, 4 skipped)
Here is the code that you can try. Its works for me. I modified based on your code snippet. I won't use this pattern in my tests though.You may not want to write protractor-cucumber test using the pattern you are following. One should always use validation/assertions in step definition code. if you do validation in page object, even your validation fails, your test still will show passed.
login_steps.js
var LoginSteps = function() {
var LoginSteps = require("../pages/pages.js");
browser.ignoreSynchronization = true;
this.World = function MyWorld() {
this.page = LoginSteps;
};
this.Given(/^the page is open$/, function (callback) {
this.page.login_page.get();
callback();
});
};
module.exports = LoginSteps;
pages.js:
module.exports = {
shipments_page: require('./shipments_page.js'),
login_page: require('./login_page.js'),
};
If I interpreted correctly this is what you want. You have only to change page.js a little.
module.exports = function() {
this.shipments_page = require('./shipments_page.js');
this.login_page = require('./login_page.js');
};
Please try this. I cannot test at the moment :=)

How to use HTML DOM using npm test (CLI)

I am trying to find a way to run npm test using mocha over a HTML DOM. In this case, I am using the global document to retrieve a table out of the DOM. However, when I run npm test I get something like the error:
ReferenceError: document is not defined
at /home/luiz/Projects/linguist-unknown/src/scripts/ling-loader.js:92:61
at extFunc (/home/luiz/Projects/linguist-unknown/src/scripts/ling-loader.js:49:11)
at Array.every (native)
at Utilities.tryMatchUrlExtension (/home/luiz/Projects/linguist-unknown/src/scripts/ling-loader.js:60:25)
at Utilities.<anonymous> (/home/luiz/Projects/linguist-unknown/src/scripts/ling-loader.js:90:16)
at xhr.onload (/home/luiz/Projects/linguist-unknown/src/scripts/ling-loader.js:24:11)
at dispatchEvent (/home/luiz/Projects/linguist-unknown/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:591:25)
at setState (/home/luiz/Projects/linguist-unknown/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:614:14)
at IncomingMessage.<anonymous> (/home/luiz/Projects/linguist-unknown/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:447:13)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickCallback (internal/process/next_tick.js:104:9)
1) should refresh table
16 passing (3s)
1 failing
1) Loader Utilities should refresh table:
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
I understand that the document is undefined and that I need to, somehow, create one myself, however, I believe that my main problems are:
My first time using npm and mocha and I cannot find anything related to it in their documentation.
Mostly, all problems people have regarding that are related to webbrowsers // I am using CLI, it will be tested with Travis on Github
In my code below you'll see that I solved a similar problem with XMLHttpRequest. However, I just can't figure out the best approach for including the document variable properly into my tests.
Thus, pardon me asking that shall this answer be already there on stackoverflow
My code is the following:
test-utilities.js
...
global.XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
global.jsyaml = require('../src/scripts-min/js-yaml.min.js');
global.LinguistHighlighter = require('../src/scripts/ling-highlighter.js').LinguistHighlighter;
var LinguistLoader = require('../src/scripts/ling-loader.js').LinguistLoader;
describe('Loader', function () {
var utilities = new LinguistLoader.Utilities();
it('should refresh table', function(done) {
var location = {
hostname: "github.com",
href: "https://github.com/github-aux/linguist-unknown/blob/chrome/examples/Brain/human_jump.brain",
pathname: "/github-aux/linguist-unknown/blob/chrome/examples/Brain/human_jump.brain"
};
// check if it is not breaking
utilities.refresh(location, function(langObj, table){
done();
});
});
});
...
utilities.js:
...
Utilities.prototype.refresh = function(location, callback) {
var new_url = location.href;
if (new_url === current_url || !this.isGithub(location)) {
return;
}
current_url = new_url;
if (linguistObj === null) {
linguistObj = {
path: this.getPossibleFilepath(location)
};
}
setTimeout(function() {
var downloadHelper = new DownloadHelper();
downloadHelper.load(linguistObj.path, function(objs){
this.tryMatchUrlExtension(current_url, objs, function(langObj){
var table = document.getElementsByClassName("blob-wrapper")[0]
.getElementsByTagName("table")[0];
new LinguistHighlighter.Highlighter(langObj).draw(table);
// callback for tests purposes only
if (callback) {
callback(langObj, table);
}
});
}.bind(this));
}.bind(this), 100);
};
...
Any help is appreciated. Thank you!
I found a very good tool: JSDOM. Its goal is to emulate a subset of a web browser, such as the DOM. With that, I could implement my test-utilities.js file without even touching my utilities.js file, which is pretty much what I wanted.
Here goes the resolution of the file test-utilities.js
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
global.XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
global.jsyaml = require('../src/scripts-min/js-yaml.min.js');
global.LinguistHighlighter = require('../src/scripts/ling-highlighter.js').LinguistHighlighter;
var LinguistLoader = require('../src/scripts/ling-loader.js').LinguistLoader;
describe('Loader', function () {
var utilities = new LinguistLoader.Utilities();
it('should refresh the code table', function(done) {
// Download the HTML string and parse it to JSDOM
JSDOM.fromURL("https://github.com/github-aux/linguist-unknown/blob/chrome/examples/Brain/human_jump.brain").then(dom => {
// JSDOM does not support 'innerText' and that is why I am creating this property for all objects.
var o = Object.prototype;
Object.defineProperty(o, "innerText", {
get: function jaca() {
if (this.innerHTML === undefined)
return "";
return this.innerHTML;
}
});
var location = {
hostname: "github.com",
href: "https://github.com/github-aux/linguist-unknown/blob/chrome/examples/Brain/human_jump.brain",
pathname: "/github-aux/linguist-unknown/blob/chrome/examples/Brain/human_jump.brain"
};
// check if it is not breaking
utilities.refresh(location, function(langObj, table) {
done();
});
});
});
That is working properly now! I hope it helps anyone! :D

Can I mock console in NodeJs?

In my JS test, I need to check if the console.info is called. That's why I want to mock console. However, it seems that the console variable cannot be assigned with a different object. Did I make any mistake?
Here is the code I used:
var oldConsole = console;
var infoContent;
console = {
info: function(content) {
infoContent = content;
}
};
game.process('a command');
infoContent.should.equal('a command is processed');
console = oldConsole;
You can use rewire to replace the whole of console to silence it, or to inject a mock. I use deride but sinon would also work.
var rewire = require('rewire');
var deride = require('deride');
var Game = rewire('../lib/game');
describe('game testing', function() {
var stubConsole, game;
beforeEach(function() {
stubConsole = deride.stub(['info']);
stubConsole.setup.info.toReturn();
Game.__set__({
console: stubConsole
});
game = new Game();
});
it('logs info messages', function() {
game.process('a command');
stubConsole.expect.info.called.withArgs(['a command is processed']);
});
});
I find the solution. I can change the method info of console.
console.info = function(content) {
infoContent = content;
};
The question is now why console object itself cannot be reassigned?
you can use sinon npm to count the call to a function :
it("calls the original function only once", function () {
var callback = sinon.spy();
var proxy = once(callback);
proxy();
proxy();
assert(callback.calledOnce);
// ...or:
// assert.equals(callback.callCount, 1);
});
You can find the docs here : sinonjs.org
I thought I had the same problem and my solution was using this std-mocks module:
https://github.com/neoziro/std-mocks
This has the advantage of not taking over the global "console" but allows you to see what gets logged to the stdout / stderr. This solves the problem in a different way than the question was explicitly looking for; however I believe it is a good answer for the problem the question implies and may be useful for others.
const stdMocks = require('std-mocks');
stdMocks.use(); console.log('test'); stdMocks.restore();
// => undefined [nothing gets output, stdout intercepted]
const logged = stdMocks.flush();
console.log(logged)
// => { stdout: [ 'test\n' ], stderr: [] }

Issues with minification

I decided to switch from socketIO to sockjs for my Angularjs app. I never had problems building my project before (with socketIO) which involves minification and concat but when I build my project now I think that this file is giving me issues which is from here: https://github.com/bendrucker/angular-sockjs as it's the only new file.
/*
* angular-sockjs v0.0.1
* (c) 2014 Ben Drucker http://bendrucker.me
* Based on https://github.com/btford/angular-socket-io
* License: MIT
*/
'use strict';
angular.module('bd.sockjs', [])
.provider('socketFactory', function () {
// when forwarding events, prefix the event name
var ioSocket;
// expose to provider
this.$get = function ($timeout) {
var asyncAngularify = function (socket, callback) {
return callback ? function () {
var args = arguments;
$timeout(function () {
callback.apply(socket, args);
}, 0);
} : angular.noop;
};
return function socketFactory (options) {
options = options || {};
var socket = options.socket || new SockJS(options.url);
var wrappedSocket = {
callbacks: {},
setHandler: function (event, callback) {
socket['on' + event] = asyncAngularify(socket, callback);
return this;
},
removeHandler: function(event) {
delete socket['on' + event];
return this;
},
send: function () {
return socket.send.apply(socket, arguments);
},
close: function () {
return socket.close.apply(socket, arguments);
}
};
return wrappedSocket;
};
};
});
Is there any reason why this file won't minify?
I am aware of the typical Angularjs minification issues so I've used string-injection syntax in all of my files. However, I can't see an opportunity to do that with this file and there isn't a minified file included with the Bower install.
This is the error in the browser console which looks to me like an injection issue:
Error: [$injector:unpr] http://errors.angularjs.org/1.3.0-beta.13/$injector/unpr?p0=aProvider%20%3C-%20a%20%3C-ocketFactory%20%3C-%socket
UPDATE:
To test that it was this file causing the issue I hosted the file on a CDN instead of minifying it. Everything works fine now so it must be this file causing the issue. It would be interesting to know what the problem is if anyone comes across this question.
Solved this on Github. #efeder was mostly correct (although it's this.$get and not this.get). The issue is that v0.0.1 didn't have proper annotations but v0.1 (latest) fixed that.

TypeError: Object function.....has no method 'on'

I am new to node.js and trying to create my first module.
But i am getting an error
TypeError: Object function SetAstAppLog.....has no method 'on'
My module file contains following code :
var EventEmitter = require('events').EventEmitter;
var util = require('util');
module.exports = SetAstAppLog;
util.inherits(SetAstAppLog, EventEmitter);
function SetAstAppLog(logFolderPath,fileNamePrefix,fileSize,logStreamObject) {
EventEmitter.call(this);
.
.
.
.
this.emit('objCreated');
}
and in app.js i am doing following things :
var SetAstAppLog = require('astAppLog');
var fileSize = 1024;
SetAstAppLog.on('objCreated', function () {
console.log('an object was created');
});
SetAstAppLog.on('written', function () {
console.log('Write operation completed.');
});
var objCommLogger = new SetAstAppLog(logFolderPath,logCommFilePrefix,fileSize,logCommMsg);
var objErrorLogger = new SetAstAppLog(logFolderPath,logErrorFilePrefix,fileSize,logErrorMsg);
Here, i am using node js with v0.10.21.
I am not able to find out why i am getting this error even my module file contains EventEmitter
Can anyone help to solve this issue?
You are exporting the function without calling it. You need to call it:
var SetAstAppLog = require('astAppLog')();
Edit: I failed to notice that you called the function lower in your script. You should be attaching the event handlers to the instances, not the constructor.
var objCommLogger = new SetAstAppLog(logFolderPath, logCommFilePrefix, fileSize, logCommMsg);
objCommLogger.on(...);

Categories