how can I get the current url using protractor? - javascript

I am testing a website using protractor, and jasmine. I would like to know the current url in order to verify a test.
I have tried
function waitForUrlToChangeTo(urlRegex) {
var currentUrl;
return browser.getCurrentUrl().then(function storeCurrentUrl(url) {
currentUrl = url;
}
).then(function waitForUrlToChangeTo() {
return browser.wait(function waitForUrlToChangeTo() {
return browser.getCurrentUrl().then(function compareCurrentUrl(url) {
return urlRegex.test(url);
});
});
}
);
}
and I am using this function in this way
it('should log', function() {
//element(by.model('user.username')).sendKeys('asd');
//element(by.model('user.password')).sendKeys('asd');
element(by.linkText('Acceder')).click();
waitForUrlToChangeTo("http://localhost:9000/#/solicitudes");
});

If you want to just check the current URL, then use browser.getCurrentUrl():
expect(browser.getCurrentUrl()).toEqual("expectedUrl");
But, if you need to wait until URL matches a certain value, see the next part of the answer.
Here is a working code based on the example provided by the author of the Expected Conditions:
var urlChanged = function(url) {
return function () {
return browser.getCurrentUrl().then(function(actualUrl) {
return url != actualUrl;
});
};
};
Usage:
element(by.linkText('Acceder')).click();
browser.wait(urlChanged("http://localhost:9000/#/solicitudes"), 5000);

Alecxe your answer was very helpful.
But couldn't you just code:
expect(browser.getCurrentUrl()).toEqual('whateverbrowseryouarexpectingtobein');
And if this fails, then you know you're going to the wrong place.

Since Protractor 4.0.0 you can now use expected conditions to know when your url changed.
const EC = protractor.ExpectedConditions;
browser.wait(EC.urlContains('my-url'), 5000);
The asnwer I found comes from this one, I have no real credits for it. But just in case it help.
Protractor- Generic wait for URL to change

Related

Gulp- Make sure file has comments in the beginning

I have multiple javascript files in a folder and I want to make sure that every file has comment in the beginning (that will explain the summary of file).
/*
This file will......
*/
function test () {
....
}
So is this possible using gulp-contains or something else?
I think this would be enough just to make sure if start of a file is the comment initial characters (/*)
gulp.src('./file.js')
.pipe(map(function(file, callback) {
var startWithComment = file.contents.toString().replace(/\n|\r/g, "").trim().startsWith("/*");
if (startWithComment){
// DO YOUR CHORES
}
}))
Another approach is to split the initial text to make sure if it is a valid multi-line comment.
function startsWithValidMultiLineComment(str){
try{
return str.replace(/\n|\r/g, "").trim().split("/*")[1].split("*/")[1].length > 0
} catch (e){
return false;
}
}
Following this approach str.split("/*")[1].split("*/")[0] would be your comment text
By using the regex provided by #Sajjad in previous answer. I have managed to achieve my goal. I have used gulp-if and gulp-fail instead (I find it more flexible).
Here is how I do that:
var condition = function (file) {
sFile = require('path').parse(file.path).name;
var startWithComment = file.contents.toString().replace(/\n|\r/g, "").trim().startsWith("/*");
return (!startWithComment);
}
gulp.task('taskName',
function() {
gulp.src('files/*.js')
.pipe(gulpIf(condition, fail(function () {
var message = 'Some message';
return message;
})));
});

Meteor.js, Router.go, pass router parameter but url can't show and result is wrong

I am new for Meteor.js and javascript. I faced a weird question when I tried to pass router parameter.
My code like:
Router.route('/ends/:keyword', function () {
this.render('navbar', {
to:"navbar"
});
this.render('search_list', {
to: "search_list",
data:function(){
var keywords = this.params.keyword;
var filtered = Websites.find({ "description": { $regex: keywords }});
return filtered;
}
});
},{ name: 'search.show' });
Template.search_form.events({
"submit .js-search-website-form":function(event){
var keyword = event.target.keywords.value;
Router.go('search.show',{ keyword:keyword });
}
});
For example when I submit course, I expected the url change to /ends/course, but it shows as /ends/?.
However if I type /ends/course directly in address bar, it works properly. I would be very thankful if someone can give me some clues. I spent the whole day on it, but no solution.
Try this
Router.go('search.show',{keyword:keyword},{});

protractor proper DRY for spec

We have an app with a grid of rows, having Per-page SELECT and Pagination, and would like to do e2e test which does navigation and PP selection then checks the results displayed by comparing it with result from DB (pseudo-code):
it('should check navigation and pp', function() {
for(i=0;i<SELECT.options;i++) {
element(by.repeater('SELECTOR HERE(i)')).click();
browser.wait(function which checks URL contains a segment(i));
browser.wait(function which checks if a 'loading div is displayed');
for(j=0;j<PagesForPP(i);j++) {
runExpects('for pp=i'); //contains a couple expect(someElement.text).toContain(asynResult());
element(by.css('SELECTOR(j)').click();
browser.wait(function which checks URL contains a segment(j));
browser.wait(function which checks 'loading div is displayed');
}
}
});
Where function(i) is a call dependent on current Perpage and function(j)
My question is: how can we nest the two loops in a way that protractor understands (possibly executes synchronously) using protractor.promise.controlFlow() or a better way if available.
Currently, protractor ignore functions like browser.wait(function which checks URL contains a segment(i));
Which looks like so:
waitForPageChange: function (urlSegment) {
console.log('>> Waiting for URL to contain: ', urlSegment);
var currentUrl;
return browser.getCurrentUrl().then(function (url) {
currentUrl = url;
}).then(function () {
browser.wait(function () {
return browser.getCurrentUrl().then(function (url) {
if (urlSegment) {
return url.indexOf(urlSegment) >= 0;
}
return url !== currentUrl;
});
});
});
}
And the e2e test completes before the expects are valid (ex: we're in page 1 and we're already reaching the 2 and 3 page checks => all tests fail because they're checking incorrect values.
Your waitForPageChange approach should work, I think. I believe you're missing a "return" (from the browser.wait), so the final then in the function (which is the return value of the whole function) isn't the right promise. Try this:
waitForPageChange: function (urlSegment) {
console.log('>> Waiting for URL to contain: ', urlSegment);
var originalUrl;
return browser.getCurrentUrl().then(function (url) {
originalUrl = url; // XXX this is racy, the page may have changed already
}).then(function () {
return browser.wait(function () { // this line was missing a 'return'
return browser.getCurrentUrl().then(function (url) {
if (urlSegment) {
return url.indexOf(urlSegment) >= 0;
}
return url !== originalUrl;
});
});
});
}
Note that code that does return muble.then(...).then(function() {return x; }) ends up return the promise from the last then in the chain.
Also, beware of the default case where urlSegment is not provided. You can't be sure the "originalUrl" gets initialized quickly enough. The browser could've moved on before you load that. To be reliable you probably want a separate "waitForPageToLeave(x)" that waits for the URL to change away from the provided one, and you should expect the caller to lookup that "original" URL before they make any changes. (And that would be separate from a "waitForPageToGoTo(x)" function that wait for the URL to become the given one.)

How to remove "http://" from domain name inside view

How can I remove "http://" from beginning of a URL inside view in an AngularJS app?
I have URLs in database like:
http://example.com/
http://example.com
example.com
but I only need to show
example.com
inside the view.
This deals with HTTP and HTTPS or any other URL. It uses the built-in URL class, which will handle all of the things you haven't thought of correctly.
app.filter('domain', function () {
return function (input) {
try {
var url = new URL(input);
return url.hostname;
} catch (DOMException) {
// Malformed URL. Return original (or something else).
return input; }
};
});
URLs that are correct and you might not have thought of:
http://example.com
http://example.com:8000
http://me#example.com
file://example.com
https://example.com
http://example.com/some-path
http://example.com?some-query-url
You may not need them now, but using the correct library function means your app won't break unexpectedly in future when someone tries to use it for something else.
use this filter in view
app.filter('domain', function () {
return function (input) {
var output = "",
matches;
var urls = /\w+:\/\/([\w|\.]+)/;
matches = urls.exec( input );
if (matches !== null) output = matches[1];
return output;
};
});

How to use codebird.js to search twitter API for matching users?

I'm really stuck trying to get this twitter library (https://github.com/mynetx/codebird-js) to return search results rather than a user timeline.
I can't find out where to pass the search parameters to it.
Here is my code at the moment:
var cb = new Codebird();
cb.setConsumerKey("<fill in>","<fill in>");
cb.setToken('<fill in>','<fill in>');
cb.__call('users/search', {
'user' : '<fill in>', // ??
}
);
function tweets_callback (result)
{
// do something with the result
}
But it keeps throwing an error, does anyone know how I can do this?
Not documented at all! This is how you do it:
var cb = new Codebird();
cb.setConsumerKey("<fill in>","<fill in>");
cb.setToken('<fill in>','<fill in>');
cb.__call('users/search', {
'q' : '<fill in>',
'callback' : 'search_callback',
}
);
function search_callback (result)
{
// do something with the result
}
Line 5 should be:
cb.__call('users_search', {
This is documented here: https://github.com/jublonet/codebird-js#3-mapping-api-methods-to-codebird-function-calls

Categories