In Nightwatch, I'm trying to write a command for checking the url of the current page.
When I write this directly in the test file, it looks like this:
browser.url(function (result) {
browser.assert.equal(result.value,expectedPageUrl);
});
This works perfectly, returns expected results. However, when I try to move it into the pageObject file and modify it like this:
checkUrl: function (expectedUrl) {
var _this= this;
this.url(function (result) {
_this.assert.equal(result.value,expectedUrl);
});
}
this returns the error
TypeError: this.url is not a function
What am I missing here?
The error you get is most probably because the 'url' is not defined in your second function, within the this object.
One way to solve it would be to try passing in that browser object as a parameter in your checkUrl function. and then to call it:
checkUrl: function (browser, expectedUrl) {
browser.url(function (result) {
_this.assert.equal(result.value,expectedUrl);
});
}
Related
I am trying to get some parameters form the URL and pass them on to another function.
The function for getting the parameters is like that:
function getUrlVars(callback) {
var urlVars = {};
var urlparts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
urlVars[key] = value;
});
callback(urlVars);
}
It gets the parameters just fine. The function that urlVars should be passed to, looks like this:
document.addEventListener('done', function() {
var projSelect = document.getElementById('projectSelection');
projSelect.value = urlVars[0];
});
});
};
I am calling both functions like so:
window.onload=function(){
getUrlVars(selectBox(urlVars));}
So all I am trying to do, is set the value of a selectbox according to a parameter in the URL. But I get an error, telling me that "urlVars" ist not defined.
And quite frankly, I am at my wits end. Can anybody tell me what I did wrong?
The problem you are having, is that when you are defining the method for window.onload you are passing a parameter that is not defined anywhere in your script.
Furthermore, it seems like you want to pass a callback method to urlVars, but you are passing a parameter? It is hard to tell by the code that you have provided.
Why not get the parameters you want from your select box and then send them to the desired method?
I'm trying to write a js function that triggers another, variable, function when complete. I figured I could do this by passing the second function's name as a string, but I can't get it to work. Here's my code:
logMeIn('likeThisPost');
function logMeIn(callBack) {
//First function content
$.post("/ajaxurl/",
{
login_id: login_id,
intent: 'login'
},
function(){
console.log('Logged in, refreshing header');
$.post("/secondajaxurl/",{},
function(data){
//success
if(typeof callBack!=='undefined') {
window[callBack]();
}
}
);
}
);
});
}
This should, according to my thinking, run likeThisPost after successfully completing both ajax calls in logMeIn, but instead I get this error:
window[callBack] is not a function
The function I'm calling on success definitley exists, and besides which, it doesn't look like it's even trying to call that function, but it's treating callBack as literal rather than a string.
I'm using jQuery and have everything wrapped in a $. Where am I going wrong?
With thanks to Jonas W and Rory McCrossan, the answer was to change the passed function to the function name, rather than a string, and then call the function directly rather than using window.
So logMeIn(likeThisPost) instead of logMeIn("likeThisPost") and callBack(); rather than window[callBack]();.
Thanks!
I have written a export module using protractor. it has multiple function defined inside it.
Now, I want to call one of the exported function inside another function within the same module.
My module looks like below.
module.exports = {
read_page_number_data: function {
// code here
},
read_page_data: function {
this.read_page_number_data().then(function () {
// Code here.
});
},
check_link_present: function {
// code here
},
click_link: function {
this.check_link_present().then(function () {
// Code here.
});
},
}
Now, when I call read_page_data function in my test script, I get below error.
Failed: this.read_page_number_data is not a function.
I have tried all the options given in below question. still there is no success.
protractor calling an exported function within the same module
NOTE: Before calling read_page_data function, I am calling click_link function, which internally calls check_link_present function. But this call works fine and check_link_present function gets call properly from click_link function. After this, control navigates to the page given in link.
One solution would be to assign the object to a variable specific to your module.
e.g.
module.exports = myModule = {
//...
}
Then you can call your functions within the module with myModule.read_page_number_data() etc.
You can find an example JSFiddle here.
Note on this context
One thing to keep in mind is that this can change it's context depending on how the parent function is called, which could be why it is working for click_link but not for read_page_data.
You can find more information on the this keyword here.
Why don't try like below. This is one of the best practices for Page Object Model test framework.
var PageName = function(){
this.firstMethod = function(){
//logic
};
this.secodnMethod = function(){
//logic
};
}
module.exports = new PageName();
How can I define a Meteor method which is also callable in a template helper?
I have these two files:
file: lib/test.js
Meteor.methods({
viewTest : function (str) {
return str;
}
});
file: client/myView.js
Template.helloWorld.helpers({
txt : function () {
var str = Meteor.call('viewTest', 'Hello World.');
return str;
}
});
When I give "str" a normal string everything works fine. But in this case my template does not get any value. I defined - for the test - in the same file where the method is a normal function and tried to call the function. The error I got was that the function does not exist. So I think that Meteor tries to render the template before it knows anything about the methods I defined for it. But I think that this is a bit unusual - isn't it?
There is now a new way to do this (Meteor 0.9.3.1) which doesn't pollute the Session namespace
Template.helloWorld.helpers({
txt: function () {
return Template.instance().myAsyncValue.get();
}
});
Template.helloWorld.created = function (){
var self = this;
self.myAsyncValue = new ReactiveVar("Waiting for response from server...");
Meteor.call('getAsyncValue', function (err, asyncValue) {
if (err)
console.log(err);
else
self.myAsyncValue.set(asyncValue);
});
}
In the 'created' callback, you create a new instance of a ReactiveVariable (see docs) and attach it to the template instance.
You then call your method and when the callback fires, you attach the returned value to the reactive variable.
You can then set up your helper to return the value of the reactive variable (which is attached to the template instance now), and it will rerun when the method returns.
But note you'll have to add the reactive-var package for it to work
$ meteor add reactive-var
Sashko added a neat little package called meteor-reactive-method to solve this problem.
$ meteor add simple:reactive-method
Template.helloWorld.helpers({
txt: function() {
return ReactiveMethod.call('viewTest', 'Hello World.');
}
});
As I point out in common mistakes, helpers should be side-effect free, so I'd use this technique with caution. However, it's a really handy shortcut for cases where:
The helper should fire only once (it doesn't depend on reactive state).
The invoked method doesn't mutate the database.
You need to interface your return value with a Session variable as the request is asynchronous:
Template.helloWorld.helpers({
txt : function () {
return Session.get("txt") || "Loading";
}
});
Template.helloWorld.created = function() {
Meteor.call('viewTest', 'Hello World.', function(err, result) {
Session.set("txt", result);
});
}
So .rendered should be called once when your template loads (at least it should with the newer version of Meteor.)
The value would be called and displayed. Otherwise it would say "Loading".
Methods on the client side are asynchronous, and their return value is always undefined. To get the actual value returned by the method, you need to provide a callback:
Meteor.call('method', 'argument', function(error, result) {
....
});
Now, there's no easy way to use the result in your helper. However, you can store it in your template as a data object and then return it in the helper:
Template.template.created = function() {
var self = this;
self.data.elephantDep = new Deps.Dependency();
self.data.elephant = '';
Meteor.call('getElephant', 'greenOne', function(error, result) {
self.data.elephant = result;
self.data.elephantDep.changed();
});
};
Template.template.showElephant = function() {
this.elephantDep.depend();
return this.elephant;
};
This is expected behavior. You are not using methods as they are intended.
Your code defines a server method viewTest and a corresponding method stub on the client with the same name.
Meteor.call('viewTest', 'Hello World.'); remotely calls viewTest on the server and in parallel runs the stub on the client.
Regarding the return value of the stub please see the documentation here, in particular:
On the client, the return value of a stub is ignored. Stubs are run
for their side-effects: they are intended to simulate the result of
what the server's method will do, but without waiting for the round
trip delay.
Regarding the return value of the server method please see the documentation here, in particular:
On the client, if you do not pass a callback and you are not inside a
stub, call will return undefined, and you will have no way to get the
return value of the method. That is because the client doesn't have
fibers, so there is not actually any way it can block on the remote
execution of a method.
There is a fine little package for this by #msavin:
https://atmospherejs.com/msavin/fetcher
If the following possible?
I wish to move the alert(result) into a function and to dynamically call it.
Current
$.ajax(this.href, {
success: function (result)
{
alert(result);
AjaxComplete();
}
});
My Attempt - not working
$.ajax(this.href, {
success: function (result)
{
window["MyAlert(result)"]();
AjaxComplete();
}
});
function MyAlert(result)
{
alert(result);
}
Is this possible?
Why can't you just do this?
MyAlert(result);
If MyAlert is a part of the window object, it's already a global.
Unless you want to call an arbitrary function by name (which isn't really good practice, IMO), which you can do like this:
window[function_name_string](argument);
window["MyAlert(result)");
is invalid syntax (missmatching [ and ), wrong function name, and not calling it at all, just getting it..). Should be
window["MyAlert"](result);
if you want to call it like that, but I see no reason why you couldn't just call it normally, as Blender mentioned.