Testing a AngularJS directive that uses Popcorn.js - angularjs

I'm working on a new project that uses AngularJS, one of the goals that we have for this project is that it's build using TDD. I'm having some issues testing a directive that uses Popcorn.js to embed video.
Here is a link to some sample code
and here is a sample of the test I'm trying to run,
it('Should load HTML5 video', function() {
var videoLoadedListener = jasmine.createSpy('listener');
rootScope.$on('videoLoaded', videoLoadedListener);
element = angular.element('<player></player>');
element = compile(element)(rootScope);
expect(element.find("video").length).toBe(1);
expect(videoLoadedListener).toHaveBeenCalled();
});
I'm getting an error from the test, 'Specified target player was not found.' which is from Popcorn.js not being able to find the div to insert the video into.
I'm using Karma with both PhantomJS and Chrome. Code seems to work fine, it's just the test that is not working.

Related

CSS selectors not working after AngularJS upgrade

I've migrated an AngularJS application from version 1.2.26 cu 1.5.11 and I'm having some troubles with selectors.
In a directive I have this piece of code:
var menu = element.find('.menu-list');
var menuWidth = menu.innerWidth();
var menuItem = menu.find('li').width(menuWidth);
Where element refers to the element attribute from the link function.
After migration, this code throws an error saying: TypeError: menu.innerWidth is not a function
What do I need to modify in order to make the code work again?

Android back button not working with hybrid app ~ using onsen ui (angular js) building app using crosswalk

When I build the hybrid app using crosswalk - android Back button is not working with onsen ui framework(using angular js).
Below is the code which i have used...
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown() {
// Handle the back button
alert("Backbutton is pressed!");
var element = document.querySelector(".navigator-container");
var scope = angular.element(element).scope();
scope.popPage();
}
As #kabaehr mentioned you may need to wait for everything to be ready first. That means either of the following:
document.addEventListener('deviceready', function(){ ... });
ons.ready(function(){ ... });
The other thing which may be specific to Onsen UI is the fact that it's already doing some handling of that event, so you could try to use the API which is given for that.
Here are the docs for that API. Currently it seems like the method which you want is:
ons.setDefaultDeviceBackButtonListener(onBackKeyDown)
Although that method doesn't sound too nice so maybe the name will change in the future.
For now feel free to try if any of these options seem to work for you.

CasperJS can't access ReactJS shadow DOM

I've been trying to wait and verify for a selector that was generated by reactjs (using shadow dom elements)
However, casperjs seems unable to locate the element I was trying to check. Is this an issue for CasperJS or maybe its engine PhantomJS?
I would like to know more about on how to handle this properly.
Here's some of my code
casper.then(function(){
this.waitForSelector('#someid', function(){
// found
}, function(){
// error - always go here
}, 5000);
});
Thanks in advance

How to dynamically add a decorator after angularjs bootstrap

Is there a way in angularjs to dynamically (after angular bootstrap) to enhance a service by proxying it using the decorator pattern.
In the following plunker example I can overload my default search service (google based) but this relies on the declaration/addition of the overloading module (the yahoo one) using the app.requires dependencies of the application before the angular app is bootstrapped. This does not work once the angular application is already bootstrapped, as demoed when clicking on duckduckgo button.
I must do the decoration dynamically by injecting javascript code into the application in a migration scenario where the webapp has to be embed into a java client (using JavaFX webview) and where some actions (the ones introduced dynamically) have to replace standard behavior of the webapp.
I have tried to use some technics described by Ifeanyi Isitor in his blog without success.
One possible method might be to get a hold of the injector of the currently running application (as described at the bottom of the documentation for angular.injector). This is done by using angular.element on an element of the currently running app to get its injector().
To easily get a hold of this element, if you were to give the tag on which you've declared your app the id of mcfoggy-application-search:
<div ng-app="mcfoggy.application.search" id="mcfoggy-application-search">...</div>
... you could .getElementById() and clobber the originally defined service a bit like this (as per your plunkr):
console.info('interpreting duckduckGoService.js');
var appElement = document.getElementById('mcfoggy-application-search');
var injector = angular.element(appElement).injector();
injector.invoke(['SearchService', '$log', function(SearchService, $log) {
// replace search in SearchService
SearchService.search = function(terms) {
var duckduckGoSearch = 'https://duckduckgo.com/?q=' + encodeURI(terms);
$log.info("search called: " + duckduckGoSearch);
// $window.location.href = duckduckGoSearch;
};
}]);
Maybe not as pretty as decoration, but it seems to work!
Updated plnkr

Karma tests fail but debug shows pass

I'm having an issue where I run my jasmine unit tests in Karma, and one of my unit tests that depends on an external template (AngularJS directive) doesn't pass. When I go into DEBUG mode in the browser and I view the console however, it shows that this unit test is passing and I can confirm this when I step through the unit test in the browser debugger.
I have other unit tests that also depend on external templates that are passing in Karma as expected, but just this particular test is failing in Karma, but passing the in browser console.
Does anyone have any ideas what might be causing this behavior?
EDIT:
Here's what Karma shows:
TypeError: Unable to get value of the property 'then': object is null or undefined
My project handles templates a little differently than AngularJS typically handles them. We have a templateService we created where it retrieves the correct template based on the templateUrl of a directive which looks like this
templateUrl: "navigation-template"
So I've set up Karma to pull the templates and store them in the templateCache. Then I extract the templates with the key Karma used (the file path) and re-insert them into the templateCache with the templateUrl the directive is expecting. Here's how I do it
var template = '<div>' + templateCache.get(templateFilePath) + '</div>'; }
// template files contain multiple templates so this filters out the one I want
template = $("[TemplateId='" + directiveTemplateUrl + "']", template).html();
templateCache.put(directiveTemplateUrl, template);
For all of the other tests, this works fine, but one in particular is producing the error above. What's more interesting is that if I add console logs like this
var template = '<div>' + templateCache.get(templateFilePath) + '</div>';
if (template.indexOf("undefined") > -1) { throw new Error("Template not in cache."); }
template = $("[TemplateId='" + directiveTemplateUrl + "']", template).html();
if (!template) { throw new Error("Template not found."); }
templateCache.put(directiveTemplateUrl, template);
It logs out that the template wasn't found.
Error: Template not in cache.,Error: Unexpected request: GET navigation-template No more request expected
If I DEBUG in the browser (the DEBUG button when Karma loads the browser), I can confirm the template is there and in the browser console (not the command line where Karma is running, but the F12 developer tools in the browser) it logs out that the test was successful like this
LOG: SUCCESS ButtonsDirectives NavigationDirective Should render a loading message
Here's what I know:
There are no significant differences between the failing unit test and the passing ones. It is unrelated to the order in which the unit tests run (this one just happens to run first).
I've figured it out. It turns out the template of the failing unit test contained the following:
<a href="javascript:void(0)" ... > ... </a>
While the unit tests themselves were similar, the failing test is the only template with this particular tag in it.
I was running my unit tests through Karma using IE 9 and javascript:void(0) turns out to have problems in IE 9 (I think it's the browser, not sure if this would cause an issue in other browsers. I cannot confirm with my current setup). Removing javascript:void(0) from the anchor tag resolves my issue.
EDIT:
Confirmed, it is a bug with IE 9. It works fine in Chrome.

Resources