how to specify include and exclude url patterns together in a pageMod? - firefox-addon-sdk

I want my pageMod to load for all pages except a particular domain(s).
currently i have specified
include:['*'] in the pageMod that loads it for all urls.
how can i make it avoid particular domains such as www.example.com and load for the rest?

There is no 'exclude' property for page-mod ( and after some fiddling I could not get negative lookahead assertions to work well ), so I expect the best route might be to use the tabs module instead:
var tabs = require('tabs');
tabs.on('open', function(tab) {
// some url exclusion logic?
if (tab.url.indexOf('http://example.com') !== -1) {
tab.on('ready', function(tab) {
let worker = tab.attach({
contentScriptfile: data.url('somefile.js')
});
worker.on('event', function(message) {
//...
});
});
}
});

Related

Protractor element handling

I have a question regarding how protractor handles the locating of elements.
I am using page-objects just like I did in Webdriver.
The big difference with Webdriver is that locating the element only happens when a function is called on that element.
When using page-objects, it is advised to instantiate your objects before your tests. But then I was wondering, if you instantiate your object and the page changes, what happens to the state of the elements?
I shall demonstrate with an example
it('Change service', function() {
servicePage.clickChangeService();
serviceForm.selectService(1);
serviceForm.save();
expect(servicePage.getService()).toMatch('\bNo service\b');
});
When debugging servicePage.getService() returns undefined.
Is this because serviceForm is another page and the state of servicePage has been changed?
This is my pageobject:
var servicePage = function() {
this.changeServiceLink = element(by.id('serviceLink'));
this.service = element(by.id('service'));
this.clickChangeService = function() {
this.changeServiceLink.click();
};
this.getService = function() {
return this.service.getAttribute('value');
};
};
module.exports = servicePage;
Thank you in advance.
Regards
Essentially, element() is an 'elementFinder' which doesn't do any work unless you call some action like getAttribute().
So you can think of element(by.id('service')) as a placeholder.
When you want to actually find the element and do some action, then you combine it like element(by.id('service')).getAttribute('value'), but this in itself isn't the value that you are looking for, it's a promise to get the value. You can read all about how to deal with promises elsewhere.
The other thing that protractor does specifically is to patch in a waitForAngular() when it applies an action so that it will wait for any outstanding http calls and timeouts before actually going out to find the element and apply the action. So when you call .getAttribute() it really looks like
return browser.waitForAngular().then(function() {
return element(by.id('service')).getAttribute('value');
});
So, in your example, if your angular pages aren't set up correctly or depending on the controls you are using, you might be trying to get the value before the page has settled with the new value in the element.
To debug your example you should be doing something like
it('Change service', function() {
servicePage.getService().then(function(originalService) {
console.log('originalService: ' + originalService);
});
servicePage.clickChangeService();
serviceForm.selectService(1);
serviceForm.save();
servicePage.getService().then(function(newService) {
console.log('newService: ' + newService);
});
expect(servicePage.getService()).toMatch('\bNo service\b');
});
The other thing that I'm seeing is that your pageObject appears to be a constructor when you could just use an object instead:
// name this file servicePage.js, and use as 'var servicePage = require('./servicePage.js');'
module.exports = {
changeServiceLink: element(by.id('serviceLink')),
service: element(by.id('service')),
clickChangeService: function() {
this.changeServiceLink.click();
},
getService: function() {
return this.service.getAttribute('value');
}
};
Otherwise you would have to do something like module.exports = new servicePage(); or instantiate it in your test file.
When you navigate another page, the web elements will be clear, that you selected. So you have to select again. You can select all elements that is in a page of HTML. You can click that you see. So the protactor + Selenium can decide what is displayed.
You have a mistake in your code, try this:
expect(servicePage.getService()).toMatch('\bNo service\b');

How to render a view into a string in SailsJS?

In one controller I want to render a certain view with a certain layout to send an email with the resulting string, but I obviously do not need to show the result to the user. Is there a way to use the EJS engine that I'm using to render views to achieve this? Here's my a bit simplified controller action:
setEmail: function(req, res) {
var update = {
activationToken: _getToken(),
email: req.param('email')
};
Profile.update(res.locals.profile.id, update).then(function(profile) {
res.redirect(profileUrl);
mailer.sendActivationEmail(
update.email,
res.i18n('Подтвердите свой адрес электронной почты'),
emailString); // <=== Here is where I need the string rendered from a view
});
},
Use the view-hook
Profile.update(res.locals.profile.id, update).then(function(profile) {
res.redirect(profileUrl);
sails.hooks.views.render("viewname",profile, function(err,html){
if(err) return console.log(err);
mailer.sendActivationEmail(
update.email,
res.i18n('Подтвердите свой адрес электронной почты'),
html
);
})
});
Edit: right callback
I think I would rather use a specific email module like this one:
https://github.com/niftylettuce/node-email-templates
Which can access EJS templates

Meteor Iron Router: How to handle a redirected url with double slash

I have made a redirection from the old website to the new one. The new website is built with Meteor and Iron Router. The redirected url is:
https://example.com//redirected-url
As you can see there is a double slash in this url.
For some reason I cannot work with the htaccess file of the old website to modify the regex.
So my last option is to handle this kind of route with Iron Router.
Do you know how to manage this kind of route with Iron Router ?
Update:
Here a sample of router configuration (all routes follow the same config):
Router.configure({
layoutTemplate: "layout",
loadingTemplate: "loading"
});
Router.map(function () {
this.route("route-name", {
path:"/",
template:"template-name",
waitOn: function () {
return Meteor.subscribe("list");
}
});
// catch all route for unhandled routes
this.route("notfound", {
path:"*"
});
Thanks in advance.
I am not sure it was the right thing to do, but it worked.
Template.mainTemplate.rendered = function() {
if(
window.location.pathname === "//url-example-1"
|| window.location.pathname === "//url-example-2"
|| window.location.pathname === "//url-etc"
){ Router.go("home") }
};
I did almost the same as #Carl B. Suggested, but instead or use Router.go("Home") which I dont know why didnt worked for me I used location.href javascript method.
Meteor.startup(function () {
Template.Home.rendered = function(){
if(window.location.pathname === "//"){
location.href = "/";
}
}
}
I know this is an old post, but in case someone encounters same issue.
I had same problem, The fix was to figure out why the double slash was there!
And the reason was: When I sat up the redirect url, I had an extra slash at the end of the redirect url. e.g: http://www.something.com/ I changed this to http://www.something.com and then got no more problems.

Ignore placeholder values on ajax form submit

I'm using the jQuery ajax form plugin in my WordPress plugin's settings page. Before I started using ajax, I had this script that compared text input values to placeholder values, and if they matched, set the text input value to null. But it no longer works now that I'm using ajax. With the jQuery ajax form plugin, I can pass arguments in a beforeSerialize function, or in a beforeSubmit function. I think it would need to be done in the beforeSerialize. Anyway, I'm not sure how to make this work. Here is the script that was working before I switched to ajax:
$('[placeholder]').focus(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
input.removeClass('placeholder');
}
}).blur(function() {
var input = $(this);
if (input.val() == '' || input.val() == input.attr('placeholder')) {
input.addClass('ssfa-placeholder');
input.val(input.attr('placeholder'));
}
}).blur().parents('form').submit(function() {
$(this).find('[placeholder]').each(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
}
})
});
And here is my current script for the ajax form submit:
var svn = $("#ssfa-saving"),
bck = $("#ssfa-saving-backdrop"),
svd = $("#ssfa-settings-saved");
$("#ssfa-form").ajaxForm({
beforeSend: function() {
svn.fadeIn('slow');
bck.fadeIn('fast');
},
success: function(){
svn.fadeOut('slow');
svd.delay(1000).fadeIn('slow').delay( 2500 ).fadeOut('slow');
bck.delay( 4500 ).fadeOut('slow');
}
});
Any ideas on how I can get the ajax submit (either beforeSerialize or beforeSend ) to ignore placeholder values? This first script above was a really simple solution for regular post submit. I'm hoping I can find something just as simple for ajax.
UPDATE
I worked out a basic way of doing it but it involves calling each text field that has a placeholder, so it's not exactly elegant like the original script, but this is functional:
$("#ssfa-form").ajaxForm({
beforeSerialize: function() {
var permex = $('input#exclusions');
$('input[id^=bs]').each(function(){
var bs = $(this);
if (bs.val() === 'Display Name')
bs.removeAttr('value');
});
$('input[id^=custom_]').each(function(){
var cs = $(this);
if (cs.val() === 'classname1|Display Name 1, classname2|Display Name 2')
cs.removeAttr('value');
});
if (permex.val() === '.avi, My Embarrasing Photograph, .tif')
permex.removeAttr('value');
},
beforeSend: function() {
etc.
And since it's a placeholder text, the text doesn't actually disappear when the value attribute is removed, so no one is really the wiser. I'm not over the moon with this, but it works. If I had a much larger form, this wouldn't be workable.
Open to better ideas....
Well, I played around with it quite a bit more and found a way to get the original code to work with ajax submit. It's quite simple actually. I just had to specify the element within which to search for the placeholder attr. Here it is:
beforeSerialize: function() {
$("#ssfa-form").find('[placeholder]').each(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
}
})
},
etc.
To track the issue, see:
https://github.com/mathiasbynens/jquery-placeholder/issues/30
https://github.com/mathiasbynens/jquery-placeholder/issues/197

How do I know that I'm still on the correct page when an async callback returns?

I'm building a Metro app using the single-page navigation model. On one of my pages I start an async ajax request that fetches some information. When the request returns I want to insert the received information into the displayed page.
For example:
WinJS.UI.Pages.define("/showstuff.html", {
processed: function (element, options) {
WinJS.xhr(...).done(function (result) {
element.querySelector('#target').innerText = result.responseText;
});
}
};
But how do I know that the user hasn't navigated away from the page in the meantime? It doesn't make sense to try to insert the text on a different page, so how can I make sure that the page that was loading when the request started is still active?
You can compare the pages URI with the current WinJS.Navigation.location to check if you are still on the page. You can use Windows.Foundation.Uri to pull the path from the pages URI to do this.
WinJS.UI.Pages.define("/showstuff.html", {
processed: function (element, options) {
var page = this;
WinJS.xhr(...).done(function (result) {
if (new Windows.Foundation.Uri(page.uri).path !== WinJS.Navigation.location)
return;
element.querySelector('#target').innerText = result.responseText;
});
}
};
I couldn't find an official way to do this, so I implemented a workaround.
WinJS.Navigation provides events that are fired on navigation. I used the navigating event to build a simple class that keeps track of page views:
var PageViewManager = WinJS.Class.define(
function () {
this.current = 0;
WinJS.Navigation.addEventListener('navigating',
this._handleNavigating.bind(this));
}, {
_handleNavigating: function (eventInfo) {
this.current++;
}
});
Application.pageViews = new PageViewManager();
The class increments a counter each time the user starts a new navigation.
With that counter, the Ajax request can check if any navigation occurred and react accordingly:
WinJS.UI.Pages.define("/showstuff.html", {
processed: function (element, options) {
var pageview = Application.pageViews.current;
WinJS.xhr(...).done(function (result) {
if (Application.pageViews.current != pageview)
return;
element.querySelector('#target').innerText = result.responseText;
});
}
};