Use the value of a variable in another file - javascript

Currently I am using protractor and using page object, so there is a file that I get the value of an element in a variable, but I need to call this value in another file.
vehiclePage.js
/*jshint esversion: 6 */
var basePage = require('./basePage.js');
var homePage = require('./homePage.js');
var VehiclePage = function() {
this.storeVehicleData = function() {
this.pessengersRuntValue = element(by.id('preview_ocupantes_runt')).getText();
};
};
VehiclePage.prototype = basePage; // extend basePage...
module.exports = new VehiclePage();
Now I need to use the value of the above variables in another file
checkoutPage.js
/*jshint esversion: 6 */
var basePage = require('./basePage.js');
var homePage = require('./homePage.js');
var CheckoutPage = function() {
this.getRuntValue = element(by.css('.mb10'));
this.compareValues = function() {
expect(this.getRuntValue.getText()).toContain(this.pessengersRuntValue);
};
};
CheckoutPage.prototype = basePage; // extend basePage...
module.exports = new CheckoutPage();
How can I make it work?

If you are following Page Object Design Pattern, I would say that the test should not be on the page object. I will write something like this.
VehiclePage.js
var VehiclePage = function(){
// if this is a browser testing something like this
browser.get('/vehicle');
};
VehiclePage.prototype = Object.create({}, {
runt: {
get: function(){
return element(by.id('preview_ocupantes_runt'));
}
}
});
module.export = VehiclePage;
CheckOutPage.js
var CheckOutPage = function(){
// if this is a browser testing something like this
browser.get('/checkout');
};
CheckOutPage.prototype = Object.create({}, {
runt: {
get: function(){
return element(by.css('.mb10'));
}
}
});
module.export = CheckOutPage;
TheTest.js
var VehiclePage = require('VehiclePage');
var CheckOutPage = require('CheckOutPage');
describe('testing something', () => {
var vehicle = new VehiclePage();
var checkout = new CheckOutPage();
it('should contain', () => {
expect(checkout.runt.getText()).toContains(vehicle.runt.getText());
});
});

One way to do this would be to pass a state object to both pages.
var VehiclePage = require('./vehiclePage.js');
var CheckoutPage = require('./checkoutPage.js');
class StateStorage {
constructor(){
this.savedVariable = null;
}
}
var state = new StateStorage();
var vehiclePage = new VehiclePage(state);
var checkoutPage = new CheckoutPage(state);
Then you can manipulate and access the state from both new pages.

Related

Javascript function modular approach init variable issue

I have a modular libray javascript file where I am exposing two functions
init to initalise variables from my main.html file.
execValidation function to run based on those three variables collections initialised through main file.
For example:
var libraryModule = (function () {
var arVals = {};
var webFormData = {};
var rules = [];
function init(arVals, webFormData, rules) {
//init all variables to global variables to use in execute Validations
this.arVals = arVals;
this.webFormData = webFormData;
this.rules = rules;
}
//only passing RuleID, but it has dependencies of other variables, which I
//do not want to pass here
function execValidation(ruleID) {
//debugger;
//Load arVals, webFormData and Rules from init
var webFormData = this.webFormData;
var arVals = this.arVals;
var arVal = arVals[ruleID];
var rules = this.rules;
var rule = rules[ruleID]
console.log(arVal);
console.log(webFormData);
console.log(rules);
}
return {
execValidation: execValidation,
init : init
}
})(); // IIFE function
In My html file, I am calling like this
var arVals = {};
//calling json file using call back
ruleConfigModule.init(function (data) {
arVals = data;
});
//passing the arVals, webFormData and rules collection to init
libraryModule.init(arVals, webFormData, rules);
Only passing the ruleID
var result = libraryModule.execValidation("Rule1");
I only want to pass one variable which is RuleID from execValidation function, but the init function should setup those variables inside the js library itself. Please can anyone help, as it does not work or help to re-organise it.
JSON calling method to populate arVals
var ruleConfigModule = (function () {
function init(callback) {
loadJSON(function (json) {
callback(json);
});
}
// Let's hide this function
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'http://localhost/test/config.json', true);
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
callback(JSON.parse(xobj.responseText));
}
};
xobj.send();
}
return {
//loadJSON: loadJSON,
init: init
}
})();
Updated:
Blockquote
How do I ensure that arVals populated before the init method gets called?
This should work
function LibraryModule() {
var arVals = {};
var webFormData = {};
var rules = [];
}
LibraryModule.prototype.init = function init(arVals, webFormData, rules) {
//init all variables to global variables to use in execute Validations
this.arVals = arVals;
this.webFormData = webFormData;
this.rules = rules;
}
LibraryModule.prototype.execValidation = function execValidation(ruleID) {
//debugger;
//Load arVals, webFormData and Rules from init
var webFormData = this.webFormData;
var arVals = this.arVals;
var arVal = arVals[ruleID];
var rules = this.rules;
var rule = rules[ruleID]
console.log(arVal);
console.log(webFormData);
console.log(rules);
return rules;
}
let libraryModule = new LibraryModule();
libraryModule.init({
rule: 'TEST'
}, {
rule: 'TEST'
}, {
rule: 'TEST'
})
var result = libraryModule.execValidation("rule");
console.log(result);

How to make a "getParent" function in a Javascript file directory

I'm making a file system, but can't figure out how to add a "parent" property.
currently I think my issue is that I can't call a function that hasn't been declared yet, but I don't see how to escape this circular logic then.
the current error is:
Uncaught TypeError: inputDir.getParentDirectory is not a function
and my code is:
var file = function(FileName,inputDir,isDir){
this.Name=FileName;
this.CurrentDir=inputDir;
this.isDirectory = isDir;
this.size = 0;
this.timeStamp = new Date();
if(isDir===true){
this.subfiles = [];
}
if(inputDir!==null){
this.parentDir = inputDir.getParentDirectory();
}
this.rename = function(newName){
this.Name = newName;
};
this.updateTimeStamp = function(){
this.timeStamp = new Date();
};
};
file.prototype.getParentDirectory = function(){
return this.parentDir;
};
var fileSystem = function(){
this.root = new file("root",null,true);
this.createFile = function(name,currentDirectory,isDirectory){
var f = new file(name,currentDirectory,isDirectory);
currentDirectory.subfiles.push(f);
};
};
var myComputer = new fileSystem();
myComputer.createFile("Desktop","root",true);
You are passing a string to inputDir which causes the error you are seeing since the getParentDirectory() method is defined for file prototype, not string. Instead you need to pass in an instance of file. Another option would be to write code to lookup an instance of file by string.
var file = function(FileName,inputDir,isDir){
this.Name=FileName;
this.CurrentDir=inputDir;
this.isDirectory = isDir;
this.size = 0;
this.timeStamp = new Date();
if(isDir===true){
this.subfiles = [];
}
if(inputDir!==null){
this.parentDir = inputDir.getParentDirectory();
}
this.rename = function(newName){
this.Name = newName;
};
this.updateTimeStamp = function(){
this.timeStamp = new Date();
};
};
file.prototype.getParentDirectory = function(){
return this.parentDir;
};
var fileSystem = function(){
this.root = new file("root",null,true);
this.createFile = function(name,currentDirectory,isDirectory){
var f = new file(name,currentDirectory,isDirectory);
currentDirectory.subfiles.push(f);
};
};
var myComputer = new fileSystem();
myComputer.createFile("Desktop",myComputer.root,true);
console.log("myComputer:", myComputer);
console.log("Desktop:", myComputer.root.subfiles[0]);

How to properly structure class in Node.js

I have a class called TileStreamer that I am currently defining as follows:
function TileStreamer {
};
This class has constants, which I define as follows:
// Tiles are 256 x 256 pixels
TileStreamer.prototype.TILE_SIZE = 256;
// Header size in bytes
TileStreamer.prototype.HEADER_SIZE = 28;
// Various table entry sizes in bytes
TileStreamer.prototype.RESOLUTION_ENTRY_SIZE = 12;
TileStreamer.prototype.TILE_COUNT_SIZE = 4;
TileStreamer.prototype.TILE_ENTRY_SIZE = 12;
// Offsets within header
TileStreamer.prototype.WIDTH_OFFSET = 3;
TileStreamer.prototype.HEIGHT_OFFSET = 4;
TileStreamer.prototype.NUM_TABLES_OFFSET = 7;
TileStreamer.prototype.UNPOPULATED_OFFSET = 12092;
There also other variables. These variables are important because they need to be accessible from other classes. They get their values within the methods of this class. This is what I am unsure of as far as structure. What I'm currently trying is:
TileStreamer.prototype.header;
TileStreamer.prototype.resolutionEntry;
TileStreamer.prototype.resolutionTable;
TileStreamer.prototype.filepath;
TileStreamer.prototype.s3;
TileStreamer.prototype.level;
TileStreamer.prototype.ncols;
TileStreamer.prototype.nrows;
TileStreamer.prototype.nlevels;
TileStreamer.prototype.toffset;
TileStreamer.prototype.tsize;
TileStreamer.prototype.modifiedTime;
TileStreamer.prototype.tile;
TileStreamer.prototype.host;
TileStreamer.prototype.bucket;
This class also has methods such as:
TileStreamer.prototype.Init = function(filepath, index, s3config){
var retval = false;
AWS.config.update({accessKeyId: s3config.access_key, secretAccessKey: s3config.secret_key});
var blc = new BlockLibraryConfigs();
var awsConfig = blc.awsConfig;
AWS.config.update({region: awsConfig.region});
var aws = new AWS.S3();
var params = {
Bucket: s3config.bucket,
Key: s3config.tile_directory + filepath,
Range: 'bytes=0-' + (this.HEADER_SIZE - 1)
};
aws.getObject(params, function(err, data){
if(err == null){
TileStreamer.modifiedTime = data.LastModified;
var header = bufferpack.unpack('<7I', data.Body);
TileStreamer.header = header;
TileStreamer.nlevels = header[TileStreamer.NUM_TABLES_OFFSET];
if(TileStreamer.nlevels == 5){
TileStreamer.level = 0;
TileStreamer.ncols = Math.ceil((header[TileStreamer.WIDTH_OFFSET] * 1.0) / TileStreamer.TILE_SIZE);
TileStreamer.nrows = Math.ceil((header[TileStreamer.HEIGHT_OFFSET] * 1.0) / TileStreamer.TILE_SIZE);
}
}
});
};
The method above should set some of the values of the variables, such as modifiedTime so that I can access it in another class such as:
TileStreamer = require('tilestreamer.js');
var ts = new TileStreamer();
ts.Init(parPath, index, config);
var last_modified = ts.modifiedTime;
Just put any public properties you want to initialise when the object is created, directly in the init function. Here's a small example...
function TileStreamer() {
};
TileStreamer.prototype.Init = function() {
this.modifiedTime = new Date();
};
var ts = new TileStreamer();
ts.Init();
console.log(ts);
jsfiddle example
https://jsfiddle.net/v6muohyk/
To get around the issue you're having with setting the object properties in a callback from an asynchronous function, just create a locally accessible variable to reference the object that you are creating at that time...
TileStreamer.prototype.Init = function() {
var thisTileStreamer = this;
asynchFunction(function(err, data) {
thisTileStreamer.modifiedTime = data.lastModified;
});
};
To take it one step further, if you need to execute some code after the init function has completed, then that will require waiting for the asynchronous function to complete, as well. For that, pass a further parameter to init, that is a function to be executed after all the work is done...
TileStreamer.prototype.Init = function(callback) {
var thisTileStreamer = this;
asynchFunction(function(err, data) {
thisTileStreamer.modifiedTime = data.lastModified;
callback();
});
};
var ts = new TileStreamer();
ts.Init(function() {
// put code here that needs to be executed *after* the init function has completed
alert(ts.modifiedTime);
});

Javascript: Calling private in a outside javascript file with JSON data

I am trying to call the method getTitulo, getDuracion and getLink inside the cancion.js file but when i call the function it returns the following error: "listaCanciones_Lcl[i].getTitulo is not a function". I have searched in different websites but i didnt got lucky with finding an answer. Hopefully someone here can give me some help, i will gladly appreciate it!
//Logic.js file
var listaCanciones = [],
ejecuTitulo = '',
ejecuDuracion = '',
ejecuLink = '';
var btnGenerarLista = document.getElementById("addList").addEventListener("click", agregarCanc);
var btnAgregarLista = document.getElementById("gnrList").addEventListener("click", llenarTabla);
function agregarCanc (){
var nameSong = document.querySelector('#nameSong').value;
var duraSong = document.querySelector('#duraSong').value;
var linkSong = document.querySelector('#linkSong').value;
var objCancion = new Cancion(nameSong, duraSong, linkSong);
listaCanciones.push(objCancion);
var listaCancionesJson = JSON.stringify(listaCanciones);
localStorage.setItem('json_canciones', listaCancionesJson);
}
function llenarTabla (titulo){
var celdaTitulo = document.querySelector('#tituloList'),
celdaDuracion = document.querySelector('#duracionList'),
celdaLink = document.querySelector('#linkList'),
listaCanciones_Lcl = JSON.parse(localStorage.getItem('json_canciones'));
for(var i=0; i<listaCanciones_Lcl.length;i++){
// Acceder a lista canciones
I am getting an error in this line, where is says "getTitulo" is not a function but i dont really know why?
var nodoTextoTitulo = document.createTextNode(listaCanciones_Lcl[i].getTitulo()),
nodoTextoDuracion = document.createTextNode(listaCanciones_Lcl[i].getDuracion()),
nodoTextoLink = document.createTextNode(listaCanciones_Lcl[i].getLink());
// Create td
var elementoTdTitulo = document.createElement('td'),
elementoTdDuracion = document.createElement('td'),
elementoTdLink = document.createElement('td');
// Celda Id Append Child
elementoTdTitulo.appendChild(nodoTextoTitulo);
elementoTdDuracion.appendChild(nodoTextoDuracion);
elementoTdLink.appendChild(nodoTextoLink);
// Fila Append Child
celdaTitulo.appendChild(elementoTdTitulo);
celdaDuracion.appendChild(elementoTdDuracion);
celdaLink.appendChild(elementoTdLink);
}
}
//Cancion.js File
var Cancion = function(pTitulo, pDuracion, pLink){
var id = 0;
var titulo = pTitulo;
var duracion = pDuracion;
var link = pLink;
this.getId = function (){
return id;
};
this.setTitulo = function (pTitulo){
titulo = pTitulo;
};
this.getTitulo = function(){
return titulo;
};
this.setDuracion = function(pDuracion){
duracion = pDuracion;
};
this.getDuracion = function(){
return duracion;
};
this.setLink = function (pLink){
link = pLink;
};
this.getLink = function(){
return link;
};
};
First, make sure you are loading the Cancion.js file before the others in your HTML. Your problem is that when you parse the JSON back out of local storage, Cancion is not a known object, so getTitulo is undefined. You'll have to do listaCanciones_Lcl[i].titulo; instead.
And another change you'll need is to loosen the scope of your variables. The reason you need this.x = pX is because before JSON.stringify(new Cancion(1, 2, 3)) just returned "{}". With this code it returns "{"id":0,"titulo":1,"duracion":2,"link":3}", which I think is what you were after.
function Cancion(pTitulo, pDuracion, pLink){
this.id = 0;
this.titulo = pTitulo;
this.duracion = pDuracion;
this.link = pLink;
this.getId = function (){
return this.id;
};
this.setTitulo = function (pTitulo){
this.titulo = pTitulo;
};
this.getTitulo = function(){
return this.titulo;
};
this.setDuracion = function(pDuracion){
this.duracion = pDuracion;
};
this.getDuracion = function(){
return this.duracion;
};
this.setLink = function (pLink){
this.link = pLink;
};
this.getLink = function(){
return this.link;
};
};
var objWithFunction = {
name: 'Object with Function',
getName: function() { return this.name }
};
undefined
objWithFunction.getName() // --> "Object with Function"
var string = JSON.stringify(objWithFunction)
string // -=> "{"name":"Object with Function"}"
JSON is for data only..
Better you create a model, and fill it with data.. but this model has to exist in your application.. or you load the model parallel to your data..
function SomeThing() {};
SomeThing.prototype.getName = function() { return this.name };
var Thing1 = new SomeThing(JSON.parse("{name:'ThingOne'}"));
Thing1.getName(); // ThingOne

javascript inheritance - '...is not defined'. Namespace issue?

I have a 'class' called ModuleSelector that grabs a list of modules from a server and displays them as clickable toggle buttons. I'm trying to create a class called Module that extends the ToggleButton class and is only visible to the ModuleSelector.
The problem I'm having is that the line:
Module.prototype = new ToggleButton(); is giving an error: ToggleButton is not defined.
I don't understand why it cannot be found, because I can create new instances of ToggleButton inside the Module function, for example.
ModuleSelector.js
(function() {
function Module(id,name){
this.moduleID = id;
this.moduleName = name;
this.topics = [];
this.addTopic = function(topic){
this.topics.push(topic);
}
}
Module.prototype = new ToggleButton();
Module.prototype.constructor = Module;
var ModuleSelector = function (id) {
this.initialize(id);
};
var p = ModuleSelector.prototype = new createjs.Container();
p.Container_initialize = p.initialize;
p.initialize = function (id) {
this.Container_initialize();
//.....
};
window.ModuleSelector = ModuleSelector;
}());
ToggleButton.js
(function() {
var ToggleButton = function(text) {
this.initialize(text);
//....code
};
var p = ToggleButton.prototype = new createjs.Container();
p.Container_initialize = p.initialize;
p.initialize = function(text) {
this.Container_initialize();
};
window.ToggleButton = ToggleButton;
}());

Categories