I'm trying to write some functional tests using Polymer's web-component-tester. I need to enter in some values into a search filter, triggering an onkeyup event. Can I make calls to WebDriver from a Mocha test?
You may want to take a look on this repo: https://github.com/PolymerElements/iron-test-helpers
It's Polymer's test helpers which will help you to mock interactions inside the component.
var element = fixture('basic');
var input = Polymer(element).querySelector('input[type="search"]');
MockInteractions.pressAndReleaseKeyOn(input, 65, [], 'A');
MockInteractions.pressEnter(input);
Take a look on an example test case here: https://github.com/PolymerElements/gold-cc-expiration-input/blob/95fa373eab5ddb557a2196d4186c283726b8c5f1/test/basic.html
Related
I want to use indexedDB with lit-element. To do so, I imported #polymer/app-storage/app-indexeddb-mirror in my lit-element project.
A copy of my code is here.
The value in the data attribute is not saved to indexedDB. No error is thrown.
Is there any incompatibility between the #polymer webcomponents and lit-element ?
Since <app-indexeddb-mirror> is just a web component, you can use it's API in any DOM-friendly library, including in lit-html.
For example:
render() {
return html`
<app-indexeddb-mirror
key="indexKey"
data="${this.data}"
#persisted-data-changed="${this.persistedDataChanged}">
log
</app-indexeddb-mirror>
`;
}
Note that lit-html has a different syntax for binding event listeners to element.s whereas with Polymer templates, you might add an attribute like
static get template() {
return html`<input on-change="methodName">`
}
With lit-html, the syntax for binding an event listener uses # in place of on-, and does not automatically dash-case your event names, so you could use:
html`<my-el #eventName="${referenceToFunction}"></my-el>`
where referenceToFunction is a direct reference to the event handler.
Note also that you don't need to create a lambda expression to pass the event to the instance method, since lit-html will auto-bind that function for you.
That all being said, consider using something like KV-Storage, idb or idb-keyval for simpler cases, as you'll end up shipping much less JavaScript to your clients that way, since you won't have to shlep along the entire Polymer library with you.
I've a View and Utility classes and wanted to hook-in the Utility method once View's job is done. So wanted to call the utility method (to add behavior to the view) once View's render call is done.
Using ES6 Proxy API, Is there a way to execute a method before / after executing the main method ? (aka method interceptions)
Similar to YUI3 Do API.
http://yuilibrary.com/yui/docs/api/classes/Do.html
Yes there is a way. Actually I'm trying to build the same thing and as long as you use a synchronous context I already got it working. Have a look at the code examples in the issue I created for my problem: stack overflow when returning an ES6 proxy through a promise
What you need to do to intercept the call is to use the ES6 proxy to get notified of the get-call that takes place to retrieve the function before the method is actually called.
In my example you can see that you get all the information about the call like what method was called with which parameters and also who called it and on which target it was originally called.
I want to use something like Nunjucks render, but with another function. For example addglobal.
Is it possible?
The typical other way to add variables would be to use Nunjucks Enviorment's and use addGlobal.
Gulp nunjucks render is built so that it handles it's own environments (as default nunjucks behavior), and as you stated you can pass variables as an object on the render call.
That being said, it does give you the ability to control your own environment it looks like. After some tinkering I was able to create my own environemnt using:
var nunjucksRender = require('gulp-nunjucks-render');
var nunEnv = new nunjucksRender.nunjucks.Environment([loaders], [opts]);
At that point you can handle it manually as per the Enviroment doc listed above, and use addGlobal as you desire. It will be a bit more work though then the default usage described here, https://github.com/carlosl/gulp-nunjucks-render
I've been writing some functional tests in Mocha, changing items and then checking if the changes propagated correctly. Currently, I'm using window timeouts to give Polymer time to update elements, but this feels like a hack. The developer guide outlines a few different observation hooks, but I'm not sure which one I should call.
The one that sounds the closest is a recommendation to attach an async call to a propertyChanged event. However, many items use propertyChanged, will attaching an async task to a propertyChanged event reliably call the async task after the element's methods attached to the original propertyChanged have been called?
Bonus points for information on whether the given solution is forward compatible with Polymer 1.0 (or .8/.9).
I was looking in the wrong place, the right place is the async portion of Polymer's testing how-to. The right function to use is flush(callback), which will "trigger a flush of any pending events and observations, ensuring that notification callbacks are dispatched after they have been processed."
Their documentation globs tests together, I prefer individual elements for each test-suite and each test. This is especially helpful when debugging functional tests as the changes are preserved and it's easier to setup break points:
before(function(done){
nonMatchingEl.search = "";
flush(done);
});
test('updates the "pre" property', function() {
assert.equal(nonMatchingEl.pre, 'prematch-hello-postmatchhello');
});
//test two ...
I'm After several days learning angularJS through converting my standart JS app to a ng one.
I was wondering about this simple scenario:
I have a global function called fb_connect(),
it can be used from any page (or any controller if you like) to make a facebook-based login.
This function makes a simple http call and receives a JSON object contain data to move on (display a pop up, login, etc...)
I read that I can define a Factory or a Service for my app and use it in any controller, which works fine.
So, I created a fb_connect factory function.
The problem is that now, in every page (every controller), I have to define that fb_connect in the constructor of every controller - for example :
function welcome($scope,fb_connect){});
What is the proper way to do this kind of actions using Angular without having to define these functions each and every time in every controller?
Thanks
Setting up factories and services is all part of the dependency injection system of Angular. Using that system is great when you need to create things that depend on other injected things. It's a big tree of dependencies. It's also nice for creating singletons, such that everywhere in your code end up using the same instance of some object.
It sounds to me like neither of these benefits apply in your case. I'd suggest just not using Angular's DI for it. You have some function defined globally, just call it directly and skip the DI. There's nothing wrong with that.
Of course you say it makes an Ajax call, so doesn't depend on the Angular $http service?
Your two options are:
Declare the function on the $rootScope
Inject it as a service
My advice is to go with making it a service. The whole purpose of services is explained in the Angular.js docs, just like this quote:
Angular services are singletons that carry out specific tasks common to web apps... To use an Angular service, you identify it as a dependency for the dependent (a controller, or another service) that depends on the service.
As you mentioned in your question, you'd prefer to not define the service in every controller you wish to use it in. With $rootScope you'll be injecting that also in every controller. So really it's a question of which you prefer, although to answer your question, the proper way of using a factory or service is to inject it into the controller you wish to use it in.
You can always put it in the $rootScope
myApp.run(function($rootScope, fb_connect){
$rootScope.welcome = function(){
};
});