Using Karma to test javascript in a play 2.2.x application - javascript

I've got a Play 2 application where my angular js dependencies (and possibly others) are declared using WebJars. When I serve up a page, I use the routing helper to fetch these javascript files.
If I want to test my javascript with Karma I need to specify the path to angular javascript files in order to run my angular dependent code. The examples I've seen on the web don't use web jars and just specify the path as ../app/assets/javascripts/lib/angular.js (or whatever). Is there a better way to do this?

I am not familiar with playframework and therefore I am not entirely understanding the restrictions it is bring to your JS Files but if this helps you can also do something like this in karma.cofig
files: [
'http://localhost:91/sample.js'
],
I performed some quick tests and it worked fine.

Related

Server settings in modern JavaScript apps

I'm looking for a solution to have server settings in a config file of some sort separate from the JS app (which I could be running in dev or prod (built) mode) but allow for the server to replace the file with a new one at random point in time (when settings have changed) and allow the JS app to pick it up and refresh it's settings.
This is mainly for setting URLs to API endpoints.
My choice of JS framework is Angular 1 and 4 but answers geared generally towards various JS frameworks/libraries are applicable.
to have server settings in a config file of some sort separate from the JS app
If you are thinking about having your server settings exposed to the front you are gonna have a bad time ;)
I will assume that you think you will keep API URLs and maybe some config along with it in a separate file while you develop. Then I can advise two approaches:
1.) SIMPLE - Have a single JS file with a single object with all the necessary API URLs and settings in a tree like structure for organisational purposes. So you have a dev, a test and production property with everything in them. Once you load app 1st thing that should the app do is load the correct settings. This is fast and doesn't require any additional knowledge. Everywhere you had something configurable hard coded you replace it with a variable that derives from that file. This should suffice for simple applications.
2.) POWERFULL - For bigger applications with loads of different dependencies and more formal and professional approach do what most people do, use NodeJs, leverage Grunt or Gulp to help you version dependencies and write scripts for different builds. It requires you to install and learn to use new stuff but offers you way more power.
Even better combine this two approaches, link the external dependencies dynamically with the build and internal via including the correct JS file with all the API information.
You can also use other npm modules to assist you with your development like precompiling CSS, lint your code, rearrange and organise files by types into folders, auto-name files or folders.
Basically, MOST of the REPETITIVE tasks you do while developing can be automated this way. This truly shines on bigger projects when all this is handled by someone who is proficient and experienced with the 2nd approach, it can save months of repetitive tasks across the team.
You could use gulp (or even npm) as a task runner to do this kind of work. Maybe this article would help? https://www.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/
The main point of a task runner is that you can set a specific variable ie prod or development, and the task runner can then switch out your config files with the present definitions for prod or dev config.

How should I load all my javascript files that contain my controllers?

I am new to Angular and making a small project.
For now, I have one large App.js where I define my route config and controllers and such.
In my index.html file, I link to this script file and everything works fine, I have multiple views and a small working app.
Now I would like to extract the controllers from my big javascript file, but then, what is the best way to include all those files? I do not want to have one script tag per file.
If you are worried about the fact that you will add the files manually over and over again, you could try to automate this process using Gulp or Grunt but it will take a bit of research. What I recommend, though, is using an already set-up generator with these systems in place for you. Such a generator would be the Hottowel generator made by John Papa, which also respect his Angular Styleguide.
Whatever you choose in the end is your preference, but I recommend looking into such generators and explore their way of doing the architecture of an Angular application and then see what suits your needs best.

How to use Angular 2 for various sites & modules using PHP as backend?

I would like to make more use of market-standards and therefore trying to start building my front-end with Angular 2, instead of my custom JS MVC-framework. However I feel getting stuck with Angular because of the things below. To describe my issues, I use a very basic example of a PHP-website with 2 simple modules.
In my current PHP-project I have 2 separate (non interrelated) modules, lets say a contact-module and a review-module, they are on the same page.
On the client side both modules download JSON-data and post JSON-data to the PHP-webservice running on port 80.
Question 1
Is it correct that for both (non interrelated) modules I need to create an Angular 2 app? So creating 2 Angular apps?
Question 2
Do you have to run per module an instance of "npm start", so that on save it will keep transpiling my project-files? This will lead to having many "cmd prompts" with "npm start" running in the background right? Now its only 2 cmd prompts, but what if my site contains 10 modules doing ASYNC-activity?
Question 3
Is it possible to share the JS-library files with various apps and within various sites?
So that it does not download all the 16.000 JS-files every time you try to do some simple ASYNC-download of JSON-data and add it to the DOM?
If yes, how?
So:
C:\angular\ -> JS-Library (containing 16.000 files.... :|)
C:\sites\site1\ -> uses C:\angular\
C:\sites\site1\contact-module\ -> uses C:\angular\
C:\sites\site1\review-module\ -> uses C:\angular\
etc.
C:\sites\site2\ -> uses C:\angular\
etc.
C:\sites\site3\ -> uses C:\angular\
etc.
How to share all those 16.000 files in the Angular JS-libraries within multiple modules & projects?
Per Angular 2 app it downloads via "npm install" more than 16.000 files....., even for the most simple application you can develop!
By having 2 simple modules, it will download 32.000 files & loading 100's of files in my webbrowser for just running 2 simple modules? (sorry but really thinking WTF!! What a waste and what an overkill, right?)
Ok, maybe you can JS-pack all those JS-files later on and combine it into 1 file. But still is this not overkill?
So, can I not for example share 1 Angular library with multiple Apps? Then it "only" requires 16.000 files...
Let's say you create 5 websites. For every website you have to add 16.000 JS-files, only because you need to do some simple ASYNC-request and add the JSON-date to your DOM. For this activity you already need to download 80.000 files (5 * 16.000)!
If it is also necessary to have several modules in a website requiring to do ASYNC-activity, like here the contact-module and the review-module, then it can easily become downloading millions of the same JS-files and using an awful lot of resources. And for every module to work having to use "npm install" and "nmp start" everytime to just work and see the results.. Having 10 "cmd prompt" screens running in the background to make this basic activity possible.
And all of this for just downloading some plain JSON-data from PHP-webservice and put it nicely into the dom?
Question 4
My main question, is the above the right / recommended approach? Not to start a discussion on how should you exactly use it, but is this a common way of working for PHP-website development and using Angular 2 for the frond-end? Or is there a better way of working?
Note, I am aware that PHP is in this scenario irrelevant, of course it can also be C# or JAVA as a back-end. But its to make the example more concrete.
Question 5
Then using the recommended TypeScript you will have to use "npm start" to transpile your files to JS and then it will run on localhost:3000.
I'm developing my sites in PHP and using Xampp on localhost port 80. Any experience of people that use Angular 2 for their front-end for their PHP-projects? How do you configure it so that it will refresh your localhost:80 page when you change something in your TS-file? And what if you have multiple (non interrelated) modules for which you use another Angular App? It cannot run twice on the same port right?
Any help is highly appreciated, thanks in advance.
I think the problem with your understanding is that you're mixing everything into one question: back-end (PHP), front-end (Angular), development setup (npm) etc. I'll try to give short answers to each of your questions.
Question 1
No, I wouldn't do create two angular applications. If you'll have a separate page for each module, you can use router to enable navigation without page reload.
Question 2
This depends on how you setup your development process. Usually, with modern building systems like webpack, you can configure module dependencies and how often each must built. This all can be managed through one command line instance.
Question 3
npm downloads 16000 files because it downloads sources along with built files. You'll use one built version in the production.
Question 4
I usually separate front-end and back-end development into different projects and treat them as completely separate applications communicating through REST interface.
Question 5
For usage of typescript, you'll have to use preprocessors which will be run by your building system. Try to google setting up angular 2 with webpack and a lot will be clearer to you.

Is it possible to use factory_girl.js with teaspoon?

As part of my trying to learn web development, I have reached a point were I have some coffeescript classes I would like to test inside my rails environment.
I have a rails 4.03 app that I have been working on (it is based off the rails tutorial).
During the process of learning rails, I got used to working with rspec and FactoryGirl, so I would like to try to follow a similar flow for the coffeescript if possible.
I wrote all my coffeescript as individual classes, each in there own file, so I think they should be testable.
I currently have teaspoon installed, which looks a lot like rspec. I have this working with some basic tests, but now I need to start writing real tests. Teaspoon has support for fixtures, but I noticed that there is a node.js package called factory_girl, which seems like it is a port of the ruby FactoryGirl for rspec. I installed this package using npm -install and now I have it listed in my rails folder under "node_modules".
Can someone tell me if it is possible to use this package to generate objects for testing with teaspoon, and if so how?
Update:
I am marking the answer below as accepted, because I was able to get FactoryGirl to run.
What I did was (as suggested in the answer) was to copy the factory_girl.js file into a location that could be loaded by the assets pipeline spec/javascripts/support, and then required it in the spec/javascripts/spec_helper.coffee file.
The problem is that the functionality does not seem to match what happens in rails (unless I am completely forgetting how it worked in rails). In Rails, I could define a factory for a model and the objects created would be instances of the class I was associating the factory with. Here there does not seem to be any association with the class I am trying to generated instances of. For example, only the properties I define in the factory definition are available, and none of the methods are defined on the objects.
I could be doing something completely wrong , or maybe trying to use coffeescript breaks this somehow.
Teaspoon doesn't use node (mostly), and is primarily rails based in terms of the runner foundation. On top of the rails layer, it uses Jasmine, Mocha, or QUnit as browser test frameworks.
Trying to load a node module in to that is not really easy, or possible in some cases. If factory_girl.js can be loaded into a browser in theory you could require the file (if it's in an asset path) within your spec helper and then use it however you want.
Disclaimer: I'm the primary author of Teaspoon, but have never used factory_girl.js (but have used factory_girl the gem).

How do I configure paths to my javascript files in the Jasmine / Maven autogenerated ManualSpecRunner.html?

I think the question says most of it. I have an autogenerated ManualSpecRunner.html file as created by maven / jasmine plug-in and I've got it to put itself into the deployable .war by using:
<jasmineTargetDir>${basedir}/pathForMyWebapp</jasmineTargetDir>
However, all the links to js files within the ManualSpecRunner.html are hard coded file:/// references - this is a bit mental, I want them to just be the relative paths to the files that are also in the webapp i.e.
Currently it gives me this path:
file:///home/username/code/HEAD/pathForMyWebapp/js/yui.js
whereas I need it to have the far more simple
/pathForMyWebapp/js/yui.js
I have tried changing two other variables in the maven script, but neither seems to have the desired effect, neither of these configuration options do what I need, the second having seemingly no effect:
<jsSrcDir>/pathForMyWebapp</jsSrcDir>
nor
<jsTestSrcDir>/pathForMyWebapp</jsTestSrcDir>
I've looked through the documentation but think I must be missing something (also, more notes on various config params listed in https://github.com/searls/jasmine-maven-plugin/blob/master/src/main/java/com/github/searls/jasmine/AbstractJasmineMojo.java are meant to do would be helpful so I can work out if I'm doing it wrong or if it's not possible!)
Any suggestions?
[p.s. I've changed some of the path names as they've got sensitive info in them, so please ignore their oddness!]
I think I understand the source of your confusion. It looks like you're trying to direct the target of the jasmine-maven-plugin to a directory inside your project's packaged *.war file so that you can run your specs against the code after it's deployed to a server, is that correct?
Unfortunately, the plugin wasn't designed with that use in mind. The jasmineTargetDir directory is usually left at its default value of target/jasmine and wasn't intended to be bundled with your application (it's analogous to the target/surefire-reports generated by maven-surefire-plugin for Java unit tests). So the reason that the script tags in ManualSpecRunner.html point to invalid locations is because that file is generated in order to be run from the local filesystem in a browser from the workstation that's building the project (to facilitate TDD).
All of that to say, if I'm reading your intention right, I think it'd be a cool feature to build a third spec runner that could be deployed with the app and executed remotely. (Especially if the project's Jasmine specs are functional/integration as opposed to isolated unit tests.) Unfortunately that's not something the project does yet.
I'm afraid that for now, if you needed to bundle the jasmine tests and execute them on the deployed server, you would need to copy ManualSpecRunner.html and jasmine into your src/main/webapp, fix the script tag references, and then manually maintain it as files are added and removed.
Make sense?

Categories

Resources