How to include a manifest.json file in rails? - ruby-on-rails

I have following html code in a view whose layout is false.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link rel="manifest" href="manifest.json">
Jquery is being loaded but not the manifest.json, when I view page source and look at them I get this error:
No route matches [GET] "/manifest.json"
Even though I have included manifest.json inside the javascripts folder inside assets folder.
I also tried
<%= javascript_include_tag "manifest.json" %>
but that didn't work either..and that get routes error
I tried
<%= manifest_link_tag "manifest" %>
Again that didn't work out, gave error :
undefined method `manifest_link_tag'
I also added the manifest.json inside initializers/assets.rb but still no luck!!

I think you need to include it like this:
<link rel="manifest" href="<%= asset_path 'manifest.json' %>">

My solution is:
= tag(:link, rel: 'manifest', href: some_path)
or
= tag(:link, rel: 'manifest', href: asset_path('manifest.json'))

Related

Capybara RSpec with CSS and JS?

rails (5.1.4)
rspec-rails (3.7.2)
capybara (2.16.1)
I'm trying to create a RSpec Rails 3.7 System spec as in https://relishapp.com/rspec/rspec-rails/v/3-7/docs/system-specs/system-spec .
Here my simple spec:
require 'rails_helper'
RSpec.describe "testing system", type: :system do
it "tests the spec" do
visit root_path
click_link 'Home'
save_and_open_page
end
The problem is that Capybara does render neither CSS content nor JS content after save_and_open_page call (in the browser) - just a plain HTML. The header inside this HTML-file contains some links
<link rel="stylesheet" media="all" href="/assets/application-ea5a1efcc44a908543519edabe00e74132151ebedeef3c1601921690d9162b5e.css" data-turbolinks-track="reload" />
<script src="/assets/application-ff63e43aef379fef744a00f21a8aadf96dc2ae8e612f8e7974b231f946569691.js" data-turbolinks-track="reload"></script>
but they reference some empty files.
Is there some way to fix it?
I tried some recipes, but still no luck. I tried to precompile the assets, to move "capybara.html" into the "public" folder, but no effect.
Modifying stylesheet_link_tag is not a good solution, a much better solution is to specify Capybara.asset_host which will add a <base> tag to any saved pages. Generally this would be set to something like
Capybara.asset_host = "http://localhost:3000/"
which would then load the JS/CSS assets from your dev server which would have access to the test mode compiled assets in the public subdirectory. Note: that none of this means the page will actually be functional since JS requests will still fail, DB records won't exist anymore, etc. Also, since it saves element attributes (not properties) a checkbox you just checked will probably not be checked in the saved page. However it will give you a generally styled page you can inspect the structure of. If all you're looking for is a current image of the page you should be using the save_screenshot/save_and_open_screenshot functionality provided by most of Capybaras drivers instead.
It has to do something with your assets.
Clear cache and run rake assets:clobber and rake assets:precompile
Still no luck, then check if Capybara is configured correctly.
Check app/views/layouts/application.html.erb has the correct Rails tags for stylesheets and javascripts. Something like this:
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application' %>
On the command line, run:
rake assets:clobber
rake assets:precompile
Ensure that public/assets/ include:
.sprockets-manifest-<xyz>.json
application-<abc>.js
application-<def>.css
Open the .sprockets-manifest... file and you should see that there are application js and css files with filenames that match the actual public/assets/ files. This .sprockets-manifest file controls what actually gets included in the HTML head links and scripts when the Rails tags are replaced.
If this is still not working, ensure that the files are accessible by your user running the test (including the manifest). Occasionally lose the .sprockets-manifest file when copying files and in source control as it can appear to be hidden.
Finally, check your file log/test.log to see if there are any obvious errors being thrown during the tests.
I found a solution. Perhaps it's not the best one, but it works with me. If anybody find a better approach - let me know, please.
Run rake assets:precompile. I didn't even set RAILS_ENV=test.
Modify the stylesheet_link_tag method:
def stylesheet_link_tag2(*sources)
options = sources.extract_options!.stringify_keys
path_options = options.extract!('protocol').symbolize_keys
sources.uniq.map { |source|
tag_options = {
"rel" => "stylesheet",
"media" => "screen",
"href" => path_to_stylesheet(source, path_options)[1..-1]
}.merge!(options)
tag(:link, tag_options)
}.join("\n").html_safe
end
The idea is to turn the rendered link from this:
<link rel="stylesheet" media="all" href="/assets/application-ea5a1efcc44a908543519edabe00e74132151ebedeef3c1601921690d9162b5e.css" data-turbolinks-track="reload" />
to this:
<link rel="stylesheet" media="all" href="assets/application-ea5a1efcc44a908543519edabe00e74132151ebedeef3c1601921690d9162b5e.css" data-turbolinks-track="reload" />
eliminating the leading slash in the href attribute value (since we don't have a server running but just a saved HTML-page).
Replace the code inside the header in \app\views\layouts\application.html.erb to:
<% if Rails.env.test? %>
<%= stylesheet_link_tag2 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<% else %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<% end %>
Write a spec like this:
require 'rails_helper'
RSpec.describe "testing system", type: :system do
it "tests..." do
visit root_path
click_link 'Home'
save_and_open_page Rails.root.join( 'public', 'capybara.html' )
end
end
Add to .gitignore:
/public/capybara.html
Do the same thing with the JS-content.
UPDATE:
If you don't like modifying \app\views\layouts\application.html.erb you can do some monkey patching:
include ActionView::Helpers::AssetTagHelper
alias_method :old_stylesheet_link_tag, :stylesheet_link_tag
def stylesheet_link_tag2(*sources)
options = sources.extract_options!.stringify_keys
path_options = options.extract!('protocol').symbolize_keys
sources.uniq.map { |source|
tag_options = {
"rel" => "stylesheet",
"media" => "screen",
"href" => path_to_stylesheet(source, path_options)[1..-1]
}.merge!(options)
tag(:link, tag_options)
}.join("\n").html_safe
end
def stylesheet_link_tag(*sources)
if Rails.env.test?
stylesheet_link_tag2(*sources)
else
old_stylesheet_link_tag(*sources)
end
end
I usually put such code into app\helpers\application_helper.rb and add include ApplicationHelper into app\controllers\application_controller.rb
UPDATE 2
Setting Capybara.asset_host = "http://localhost:3000/" as #Thomas Walpole advised doesn't work. That's right - how can it work if http://localhost:3000/ is unavailable (AFTER the spec ran)? Of course - when I call save_and_open_page the HTML-file opens with a file://.... address - with no HTTP-server serving it. The attempts to set
Capybara.asset_host = "file://#{Rails.root}/public"
failed - looks like the base HTML-tag supports only http-adresses - not file://... ones. I checked it in Chrome and Firefox.
So my next code proposal is such:
include ActionView::Helpers::AssetTagHelper
alias_method :old_stylesheet_link_tag, :stylesheet_link_tag
def stylesheet_link_tag2(*sources)
options = sources.extract_options!.stringify_keys
path_options = options.extract!('protocol').symbolize_keys
sources.uniq.map { |source|
tag_options = {
"rel" => "stylesheet",
"media" => "screen",
"href" => "file://#{Rails.root}/public" + path_to_stylesheet(source, path_options)
}.merge!(options)
tag(:link, tag_options)
}.join("\n").html_safe
end
def stylesheet_link_tag(*sources)
if Rails.env.test?
stylesheet_link_tag2(*sources)
else
old_stylesheet_link_tag(*sources)
end
end
This eliminates the need to call
save_and_open_page Rails.root.join( 'public', 'capybara.html' )
instead you can simply call
save_and_open_page

Why the path to assets is added after path segment ? Rails

When I added a path segment to my Ruby on Rails app /pricing the path to assets started to be added after it like this which causes 404:
GET http://localhost:3000/pricing/assets/bootstrap.min.css
This is the route:
get 'pricing/:level', :to => 'welcome2#pricing', as: "package_signup"
This is the controller:
class Welcome2Controller < ApplicationController
def pricing
#package_signup = params[:level]
end
end
This is the link on the index page linking to pricing/bronze:
<%= link_to 'package_signup bronze', package_signup_path('bronze') %><button class="btn btn-success">Get Started</button>
How can I keep the path to assets the same ? like this:
GET http://localhost:3000/assets/bootstrap.min.css
This is where bootstrap is included:
<link href='assets/bootstrap.min.css' rel="stylesheet">
Add a / (forward slash) before assets. It ensures that assets will be picked from root URL not from the current URL.
Like this:
<link href='/assets/bootstrap.min.css' rel="stylesheet">

Jasmine specs are not loading in any of the correct assets using jasmine-rails gem

I am using the jasmine-rails gem to try and get our jasmine test suite working.
In my routes right at the top I have defined the following;
mount JasmineRails::Engine => '/specs' if defined?(JasmineRails)
And that seems to work, I can browse to /specs and the title of the page is Jasmine Specs.
The issue is that none of the assets that Jasmine needs are being loaded, including the specs. In my console I am seeing;
GET http://acme.lvh.me:8081/specs/assets/jasmine-specs.css 404 (Not Found) specs:21
GET http://acme.lvh.me:8081/specs/assets/jasmine.js 404 (Not Found) specs:22
GET http://acme.lvh.me:8081/specs/assets/jasmine.css 404 (Not Found) specs:20
GET http://acme.lvh.me:8081/specs/assets/jasmine-html.js 404 (Not Found) specs:23
GET http://acme.lvh.me:8081/specs/assets/boot.js 404 (Not Found) specs:25
GET http://acme.lvh.me:8081/specs/assets/json2.js 404 (Not Found) specs:24
GET http://acme.lvh.me:8081/specs/assets/jasmine-specs.js 404 (Not Found)
I am not quite sure why /specs/ is in that path?
My jasmine.yml is;
spec_files:
- "**/*[Ss]pec.{js,coffee}"
Any help would be greatly appreciated.
I was able to fix this by created a custom template
app/views/layouts/jasmine_rails/spec_runner.html.erb
And manually looping and creating the CSS/JS includes;
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
<title>Jasmine Specs</title>
<% jasmine_css_files.each do |css_file| %>
<link href="/assets/<%= css_file %>" media="screen" rel="stylesheet" />
<% end %>
<% jasmine_js_files.each do |js_file| %>
<script src="/assets/<%= js_file %>"></script>
<% end %>
</head>
<body>
<div id="jasmine_content"></div>
<%= yield %>
</body>
</html>

Using jquery-ui-rails datepicker in an Ruby on Rails website. datepicker method not defined

I got this problem writing the website with Ruby on Rails.
bundle show
* jquery-ui-rails (4.0.1)
In app/assets/javascripts/application.js
//= require jquery.ui.datepicker
In app/assets/stylesheets/application.css
*= require jquery.ui.datepicker
In app/views/layouts/application.html.erb
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
And then in somepage.html.erb, I got
<script type="text/javascript">
$(function(){
$("#startdate").datepicker();
$("#enddate").datepicker();
});
</script>
When running it, Chrome says that
Uncaught TypeError: Object [object Object] has no method 'datepicker'
I suppose that resource not being referred properly is the cause because the problem could be fixed by adding the follows into app/views/layouts/application.html.erb
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.1/themes/base/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.1/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
These could be found at http://jqueryui.com/datepicker/. I saw demos having working datepickers without these codes. But I do not understand why it is not working in mine. Anyone got any suggestions? like something to add other than those I mentioned above?
It probably because of either of the following:
1) You are including multiple javascript files in your application.html.erb which is leading to havoc when put altogether.
2) You are using some other javascript file that also using $ just like jquery is using.
Having two same symbols is the possible cause of getting no method 'datepicker' for the jquery.
The alternative is to replace all the occurences of $ with jQuery
OR
Just wrap your jquery code insode a block like the following:
jQuery(function($){
//all jQuery code which uses $ should be here.
});

Rails ActionController::UnknownAction for favicon

I have following line in my app/views/layouts/application.html.erb
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon" />
This somehow causes following error message int he logs and the favicon is not loaded. This happens only for certain paths not for the whole application.
ActionController::UnknownAction (No action responded to images. Actions:
How to get rid of it ?
Use the favicon_link_tag helper instead:
<%= favicon_link_tag "/favicon.ico" %>
Just make sure your favicon.ico file is in the public folder... and do not forget the forward slash.
Believe me.. try prefixing images with a slash and this should work
<link rel="shortcut icon" href="/images/favicon.ico" type="image/x-icon" />

Resources