I would like to create reliable functional tests for Grails application with Geb which wouldn't take ages to run so me and and other team members can run them before each commit. I'm using Grails Asset Pipeline with CoffeeScript files split into many files and grouped using index files.
The problem is following:
In development and test environment the CoffeeScript files are compiled for the first URL hit - for the first time the page is loaded. As the application grows this takes more than one minute (especially on CI server) so each of my Geb specification needs to start with waitFor(120){...} to ensure the specification will wait until the CoffeeScript get compiled.
I could run the functional tests with -war flag but than all the CoffeeScript files present get compiled multiple times (once for every reference from the CoffeeScript file, i.e. one big bundle or the application coffee, once for index file once for the file itself). Currently the compile process fires for nearly three hundreds of files instead of two. If I try to exclude some files using the grails.assets.excludes than the files are missing from the application bundle completely.
Are there any suggestion how can compile just the files which are needed but not excluding them from bundling into other files?
The structure can be seen in our test app and core plugin.
Related
In my Rails app, I'm dynamically modifying an app/assets/stylesheets/main.scss.erb file for some RSpec tests. If I run the RSpec tests individually, they all pass fine. If I run them together, every test fails except the first one. I suspect sprockets is caching the initial change, which lets the first test pass, but never updates the cache for the subsequent tests.
Is there a way to clear the sprockets cache (I'm using sprockets 3.7.2) before each test executes and force it to reload from the current state of the files?
Update 12/12/2018: Here's a little more context about what I'm doing. I have a Rails engine that powers several applications in my company. The engine loads a stylesheet inside the engine and it also looks inside the host Rails application and loads a second stylesheet (i.e. we don't require the Rails apps to add the stylesheet to the application.css manifest file themselves; the engine handles it). We recently found a bug that prevented the engine from loading the application level stylesheet, so I fixed it and started adding some tests in the engine. My first attempt at testing was to create a page that had some special divs. The divs use CSS IDs that are defined in the various stylesheets. If the divs end up with the expected styles, I know they only got those styles from the stylesheets (which confirms that they got loaded). This strategy works, but it requires code spread out in the engine and dummy application (inside the engine). I then started experimenting with having the tests dynamically append CSS rules into the stylesheets when each test is executed. This strategy is a big improvement because it keeps all the interesting code in the test. Anyone reading a specific test can immediately see the styles that are being added, and the files that are being modified. Everything is contained in the test. Unfortunately, even though I'm resetting all the necessary files between tests, it looks like the assets cache isn't getting invalidated.
Before executing Asset Precompile (rake assets:precompile) I want to apply gulp tasks to my JavaScript files which are located here:
app/assets/javascripts/my_angular/directives/*.js
app/assets/javascripts/my_angular/controllers/*.js
So when I later run rake assets:precompile it will pick already processed-by-gulp files.
But the problem for me is that I do not want to simply overwrite existing JS files with its gulp output files since I still need original, not touched files for comfortable development.
I think I need to have two folders:
1) development_assets
2) production_assets (auto-generated folder with gulp output)
Is it possible in Rails to have different assets directories for different environments? (development, production). If yes - how to configure it?
Maybe there is another solution for my problem? Without having two separate directories... I am open to suggestions.
You can configure the assets path with config.assets.prefix = '/gulped-assets'. If you do that in config/environments/production.rb, it'll apply to production but not development, letting you still use your original files in dev. You'll need to either make sure your deploy process runs Gulp before asset compilation, or run Gulp locally and include /gulped-assets in your repository.
You can also add a preprocessor to the asset pipeline, which would leave you needing just one /assets directory. You do that by specifying a file extension and a handler, then adding the extension to all the files you want processed that way, just like you have with .sass, .erb, etc. To crib from the Rails examples, it looks like this:
module BangBang
class Template < ::Tilt::Template
def prepare
# Do any initialization here
end
# Adds a "!" to original template.
def evaluate(scope, locals, &block)
"#{data}!"
end
end
end
# config/initializers/bang.rb
Sprockets.register_engine '.bang', BangBang::Template
Then any file containing .bang in the extensions will have a ! appended to it. There's already support for a lot of different tasks out there, so perhaps you can avoid Gulp in favor of a Sprockets-only pipeline. Depending on your Gulp tasks, you might even be able to shell out and run data through them to build a hybrid pipeline.
Or, you can go the other direction and replace Sprockets with a Gulp-only pipeline. There are a lot of people doing that, and anything I'd write here would be long and only duplicate their work, so check out the gulp-rails-pipeline gem and perhaps read Gulp - a modern approach to asset pipeline for Rails developers for another angle on it.
For an application built on top of Rails (3.1.8) with ExtJS 4.1, we have the following files layout:
app/
assets/
javascript/
application.coffee
WID/
Lots of coffeescript files and folders.
public/
extjs/
ext-all-debug-w-comments.js and the whole ExtJS framework.
Our application heavily relies on the Ext loader (Ext.Require) to dynamically load files based on users rights / allowed modules. We would like to keep this functionality as much as possible, so only the required files are requested from the server. Bandwidth isn't really an issue, as the application is intranet-based (On a LAN).
In development environment, everything runs smooth. In production environment however, we are having problems. It looks like either the "rake assets:precompile" task is concatenating all files into an application.js file, and then when accessing our application the Ext loader complains that it can't find individual files (Because assets/WID/.../file.js isn't being served by the rails server).
So right now, i'm not sure what would be the best move to take... Is there anyone able to help us with a successful Rails + ExtJS production setup taking the best from the assets pipeline?
Thank you,
Pierre.
I think you should move your javascripts (and generally all the assets) from your public into vendor/assets/javascripts when you are in development environment. This way the asset-pipeline gets in charge.
EDIT: You may consider reverting your manifest file to application.js, not application.coffee. Generally it is a bad idea to rename these special files : application.css and application.js .In case you have some coffescript to add , just create a new file and place it in an asset directory.
I'm building a Rails application that is almost entirely CoffeeScript upfront. The user will never wait for a page redirect because literally everything happens on the front page (a la Twitter).
Now I've had to put all of my CoffeeScript into one file because my jQuery onLoad is complex and, while in production it will be compiled to one JS file, in testing this is not the case.
How can I either import CoffeeScript from other files in development or organize my CoffeeScript so I'm not piling 500 lines into one file (when those 500 lines contain 5/6 distinct domains)?
I have used import in SCSS to do the same thing for my stylesheets, but CS is proving a bit trickier.
The asset pipeline allows you to require different files into one file, which keeps them separate in development and compiles them to one file in production. Check out the instructions on Manifest files and Directives
Also, have you looked into RequireJS? It can work in or outside of Rails and might be the sort of thing you need.
After I deployed my upgraded Rails 2.3.x -> 3.1 (rc4) app to our test environment this afternoon, all of our stylesheets and JavaScript files were returning 404 errors. We had added the rake assets:precompile task to our post-deploy script and it took a while to determine why the assets folder didn't have the pre-compiled files we expected.
In the end, the files weren't being compiled because apparently only application.css and application.js (+ non JS/CSS files) are processed by default.
We needed to change the following configuration value as follows:
config.assets.precompile += %w( *.js *.css )
Question: why isn't this the default?
I would have expected that anything that wasn't necessary to process as a manifest file would just get copied into public/assets. Much of what I've read on the asset pipeline is essentially "stick your assets in app/assets, configure the manifest files, and it should just work". Since the assets:precompile task didn't spit out any information about what it was doing, it took a while to determine that it just wasn't looking at the files we thought it would.
Is there any reason why this would not be a good value for the precompile configuration?
Thanks!
The idea is to have all your JavaScript and CSS always loaded in one shot, rather than loading bits and pieces as you move along. That way you always have the 'world' loaded and ready to work with, rather than having to include a whole bunch of individual files here and there.
It's a bit of a larger 'up front' load, but then the browser should keep loading all the javascript from cache. So the perceived speed of the site should speed up due to having everything cached and ready to go after the first request.
This was a controversial decision to include for Rails, but so is including CoffeeScript by default. Rails has always been an opinionated framework that way.
the new sprockets-based pipeline compiles all the files in /asssets/stylesheets and /assets/javascripts get compiled into application.css and application.js, respectively, by default.
In your views, you only need to link the application files, sprockets handles the rest.
Update:
Well, you don't have to make it all into just one file... You could have an shared.js, secure.js and public.js and have them each include the parts they need...
Think of them not as javascript files, but manifest files that establish groups of javascript files which you can then include as a group with a single javascript_include_tag. While the default is to include everything in the folder into a single file, you can be always pick and choose what to include, and what not.
The 'precompile' task simply runs those manifest files and compiles the multiple files into one, while pre-processing and sass or coffee script it runs across.