protractor calling an exported function within the same module - javascript

I'm newer to using Protractor for automation, so forgive me if this ends up being a dumb question. I have a helper.js module with a bunch of functions that I or other team members can use. One of the functions from helper.js needs to call to one of the existing functions in the module.
Is this possible? I have tried several different ways to do this and so far none have worked other than to break the helper functions into a separate js file that I need to call to.
Example:
helper.js:
module.exports = {
newbrowsertab: function(){
<code>
},
anotherfunction: function(){
<code>
<call to newbrowsertab();>
<code>
},
anotherfunction2: function(){
<code>
}
};
In the call to the newbrowsertab function, I've tried:
module.newbrowsertab();
this.newbrowsertab();
self.newbrowsertab();

You could use Prototypal inheritance then:
// helper.js functions
// create object
var Util = function() {};
// extend object
Util.prototype.enterPassword = function() {
// code
};
// extend object
Util.prototype.clickLogin = function() {
// code
};
// use `this` to call functions in same module
Util.prototype.fullLogin = function() { // extend object
this.enterPassword();
this.clickLogin();
};
module.exports = new Util();
Then in your test file:
var Util = require('./path/to/helper.js);
Util.fullLogin();
etc...

Expanding on the prototypal convention.
Any functions that are only helpers for other exported functions could be named with an underscore and declared to be executed later.
function _helperFunction(){
// do something
// return something
}
var exposedFunction = function() {
// do something
var x = _helperFunction();
// Do something else
}
module.exports = {
exposedFunction : exposedFunction
};

Related

How to export and import two different function objects in JavaScript?

I use Jasmine-Node to test Javascript code.
How can one export two different function objects like Confusions1 and Confusions2 so that both are available in the Jasmine-Node test file?
My attempt looks like this:
// confusions.js
var Confusions1 = function() {};
Confusions1.prototype.foo = function(num) {
// keep track of how many times `foo` is called
this.count++;
}
module.exports = Confusions1;
// second function object
var Confusions2 = function() {};
Confusions2.prototype.foo = function() {
var a = 2;
this.bar();
};
Confusions2.prototype.bar = function() {
return this.a;
}
module.exports = Confusions2;
And my Jasmine Test file:
// confusions.spec.js
var Confusion = require('./confusions.js');
describe("chapter 1, common misconception ", function() {
describe("to assume `this` refers to the function itself: ", function() {
var confusion = new Confusion();
// some test code omitted
});
describe("to assume `this` refers to the function's scope", function() {
var confusion = new Confusion();
// test code omitted
});
});
I want it so that Confusions1 and Confusions2 from confusions.js are both usable in the two nested describe blocks within confusions.spec.js
I assume that I have to somehow initialize different objects after requiring the file var Confusion = require('./confusions.js');
Something like var confusion1 = new Confusions1(); var confusion2 = new Confusions2(); But how exactly (without splitting both Objects in two separate files)?
So you want to have a module that behaves like a container of exported values, in another words you want to export two functions:
// foo.js
var Confusion1 = function() {}
var Confusion2 = function() {}
...
exports.Confusion1 = Confusion1
exports.Confusion2 = Confusion2
Wherever you need this module, you could require this stuff like:
// bar.test.js
var confusions = require('path-to-the-foo-file')
console.log(confusions.Confusion1)
console.log(confusions.Confusion2)
Also as it seems you should check how module system that you are using works in general, check this answer: module.exports vs exports in Node.js

Creating JS library with dynamic function calling

I'm creating a JS 'library' file, But I want to encapsulate it in it's entirety within an object, to avoid contaminating namespace of the pages that include the file
The twist to this is within a function inside the library I need to call others functions within library by name, eg using window[]
The code below is just a sample there would actually be several hundred functions that could be called by name. It's this that's caused by trouble as I can't get window[] to reference the function, what's the right way to go about this?
I have tried this, in host page:
<script src= "mylib.js"></script>
var oMyLib = new cMyLib(); //there will only ever be one 'instance' of this
In mylib.js everything is contained in one function:
function cMyLib() {
this.doStuff = function () {
someFunc(this); //call another function in the lib
}
// I tried it with prototypes also
// cMyLib.prototype.doStuff = function () {
// someFunc();
// }
function someFunc(that) {
var s='anotherFunc1'
var f = window[s]; //undefined!
f();
s='anotherFunc2'
f=window[s];
f();
}
function anotherFunc1() {}
function anotherFunc2() {}
}
The functions that you want to reference by name (or actually by number, according to your comments) should be part of that object, and not accessed via window, e.g.:
function cMyLib() {
// allow call without new
if (! (this instanceof cMyLib)) {
return new cMyLib();
}
// enforce singleton
if (this.constructor.singleton) {
return this.constructor.singleton;
} else {
Object.defineProperty(this.constructor, 'singleton', {
value: this
});
}
// instruction array (no need to expose via `this`)
var insn = [];
insn[0x4c] = function lda_immediate() { ... }
// instruction execution
this.step = function() {
var opcode = memory[pc++];
if (opcode in insn) {
// `.call` ensures `this` is set inside the instruction fn.
insn[opcode].call(this);
} else {
hcf();
}
}
}
Note the extra stuff at the top - convenience code to ensure that only one cMyLib can exist.
As long as a function is in parent scope you can just reference it directly, i.e.
function someFunc(that) {
anotherFunc1();
};
will simply work.
Another thing is that classical way to do this is to wrap everything in a self-calling anonymous function, i.e.
(function() {
function anotherFunc1() {};
function anotherFunc2() {};
this.cMyLib = function() { ... };
})();
But your approach is fine as well.
If you wish to call your functions by dynamic name, then you can store them in a top level object:
(function() {
var my_functions = {
anotherFunc1: function() {},
anotherFunc2: function() {}
};
this.cMyLib = function() {
var name = 'anotherFunc1';
my_functions[name]();
};
})();
It's like creating an isolated "global" scope.
Side note: Do not use eval. It is very unsafe and slow. It will backfire at you at some point.

Global object with functions to be overriden by each project JS?

I'm wondering how I should design my javascript files.
I will have a global.js file which will be used for all projects. Then each project will have it's own project.js file, containing specific functions/overrides/settings just for that project.
So I'll want to write all my "global" functions in the global.js file:
Global = function() {
var config = {'alpha': 1};
function getConfig() {
return this.config;
}
function printConfig() {
console.log(this.getConfig());
}
};
Global.prototype.echoConfig = function() {
console.log(this.getConfig());
};
and I guess my project.js file, would look like:
var project = new Global();
Global.prototype.projFunc = function() { return 2; };
However, I haven't figured out how to get the config from global.js ?
I'm using jQuery, and have noted there's the $.extend function that looks nice, however I'd like to first set-up the structure for my global.js and project.js - in general I'd probably want to move most functions from project.js into global.js, but there might be one or two projects that only need 1 specific function for that application.
you need to have getConfig in a public scope, and since you have config declared in a "private" way, you cannot use this.config to get the config, just use config.
Global = function() {
var config = {'alpha': 1};
this.getConfig = function() {
return config;
}
function printConfig() {
console.log(this.getConfig());
}
};
Scope Tutorial

Node.js double call to require()

//lib.js
var opt = 0
exports.set = function(arg) {
opt = arg
}
exports.prn = function() {
console.log(opt)
}
///prog.js
var lib = require('./lib')
var lib2 = require('./lib')
lib.set(222)
lib2.set(333)
lib.prn()
lib2.prn()
prog.js will output:
333
333
but I need it to output:
222
333
In ohter words, opt must be unique to variable lib and to variable lib2. How to achieve that?
That's because normally nodejs caches its modules which are got via require. You may use the following helper:
// RequireUncached.js
module.exports = function(module) {
delete require.cache[require.resolve(module)]
return require(module);
}
and the usage of the helper:
var requireUncached = require('RequireUncached.js');
requireUncached("./lib");
Have in mind that this approach is considered as bad practice and should not be used. I'll suggest to wrap your logic into a function, require the module and call the function. So, every time you get a new instance.
require will not load scripts multiple times, but always yield the same instance.
If you need different environments, make your module a constructor function that allows to be instantiated multiple times. Store opt on each object for that instead of in the (global) module scope.
// lib.js
module.exports = function constr() {
var opt = 0
this.set = function(arg) {
opt = arg
};
this.print = function() {
console.log(opt)
};
};
// prog.js
var lib = require('./lib'),
inst1 = new lib(),
inst2 = new lib();
/* or short:
var inst1 = new require('./lib')(),
inst2 = new require('./lib')(); */
inst1.set(222)
inst2.set(333)
inst1.print()
inst2.print()
The way the NodeJS module system works, the output is correct and your expectations contradict the design principle here.
Each module is loaded once and only once, and subsequent calls to require simply return the reference to the pre-existing module.
Maybe what you need to do is create a class you can create one or more instances of instead of using module-level globals.
Adding to Bergi's answer, You may also try it like
// prog.js
var lib = require('./lib')(),
lib2 = require('./lib')();
lib.set(222)
lib2.set(333)
lib.print()
lib2.print()
// lib.js
module.exports = function constr() {
var opt = 0
return { set : function(arg) {
opt = arg
},
print : function() {
console.log(opt)
}
}
};
Add this line as first line of your lib.js
delete require.cache[__filename]
now your module becomes in a separate namespace each time you require it.

How to write simple, extensible, modular Javascript

I need a mechanism whereby people can extend my base code with their own modules - but I'm struggling to come-up with a simple mechanism to do that.
Example: a function called 'test' which users can extend. Each user module is loaded after the original - so each one needs to build on the last (the order they're loaded should not matter or can be controlled by naming)
I started to play with something like this
var test = function() { // the master function
console.log("1");
}
var ltest = test; // module 1
var test = function() {
ltest();
console.log("2");
}
var ltest2 = test; // module 2
var test = function() {
ltest2();
console.log("3");
}
Then, when 'test' is called, it will run everyone's code (assuming no-one forgot their callback!!)
That works, but it relies on each module declaring it's own, unique 'callback' variable (ltest, ltest2) - if someone uses the same variable, we'll get a 'call stack exceeded' as those variables are global in scope...
Can anyone suggest a cleverer/better system - or point me to some examples of the same thing?
There's loads of material on inheritance but I don't want to create new things which extend the old one - I just want to extend the old one!!
p.s. taking the anonymous function stuff from the module pattern - I got this
var test = function() {
console.log("1");
}
(function() {
var oldtest = test;
test = function() {
oldtest();
console.log("2");
}
}())
(function() {
var oldtest = test;
test = function() {
oldtest();
console.log("3");
}
}())
Which is probably the simplest solution to my question - but not necessarily the best system to use (as it's dependant on the author to remember to callback the code - a dodgy module would break everything)
The Module Pattern is what you need.
In particular the 'Augmentation' or 'Loose Augmentation' patterns :
var MODULE = (function (my) {
var old_moduleMethod = my.moduleMethod;
my.moduleMethod = function () {
// method override, has access to old through old_moduleMethod...
};
return my;
}(MODULE || {}));
You could make a function like this
function extendFunction(fn, pre, post) {
return function () {
var arg = arguments;
if (pre) arg = pre.apply(this, arg); // call pre with arguments
arg = fn.apply(this, arg); // call fn with return of pre
if (post) arg = post.apply(this, arg); // call post with return of fn
return arg;
};
}
then extend as follows
var test = function () { // the master function
console.log("1");
};
test = extendFunction(
test, // function to extend
null, // thing to do first
function() {console.log("2");} // thing to do after
);
test = extendFunction(
test,
null,
function() {console.log("3");}
);
test(); // 1, 2, 3
This is very different to the normal meaning of "extend" though, where you give new properties to Objects or set up prototype chains, and to "module" which normally involves wrapping all your code in a function expression so that you don't pollute the namespace.

Categories

Resources