Threads and processes in a Capybara/Selenium session
TLDR: This card explains which threads and processes interact with each other when you run a Selenium test with Capybara. This will help you understand "impossible" behavior of your tests.
When you run a Rack::Test (non-Javascript) test with Capybara, there is a single process in play. It runs both your test script and the server responding to the user interactions scripted by your test.
A Selenium (Javascript) test has a lot more moving parts:
- One process runs your test script. This is the process you...
Careful when writing to has_many :through associations
tl;dr: Using has_many associations with a :through option can lead to lost or duplicate records. You should avoid them, or only use them to read records.
Consider this:
class User < ActiveRecord::Base
end
class Party < ActiveRecord::Base
has_many :invitations
has_many :users, through: :invitations, include: :user, order: 'users.name'
end
class Invitation < ActiveRecord::Base
belongs_to :party
belongs_to :user
after_create :send_invite
def send_invite
...
Auto-coerced virtual attributes with Virtus
We've since created ActiveType which has a restricted subset of Virtus' features. It might be enough for your needs.
We sometimes give our ActiveRecord models virtual attributes for values that don't need to be stored permanently.
When such a virtual attribute should contain integer values you might get unexpected behavior with forms, because every param is a string and you don't get the magic type casting that Rails would give you if it ...
Whitelist Carrierwave attributes correctly
Say you have a User with a Carrierwave attribute #avatar:
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
end
When whitelisting the avatar field in the controller, you might do this:
params[:user].permit(:avatar)
But you probably want this:
params[:user].permit(:avatar, :avatar_cache, :remove_avatar)
In this example:
-
:avatar_cacheallows a newly upload image to persist through form roundtrips in the case of validation errors (something that isn't possibl...
Alan Klement: Replacing The User Story With The Job Story
I've written about the problem with user stories before. At the time, I found it better to just have the team talk over proposed changes to the product. This worked great when the team had gelled and the product is very mature; however, now I'm working with a new team and building a product from scratch. In this case, because our canvas is blank, we are having trouble getting on the same page when it comes to customer motivations, events and expectations. But today, things have turned around. I've come across a great way to use the jobs to...
Let the browser choose the protocol
Use protocol independent URLs whenever possible so that the browser will choose the protocol related to the protocol which the page is delivered with.
Example issues
- When your page is delivered via
httpsand you provide a youtube video only viahttpthe most browsers (e.g. Firefox, Chrome) won't display the video. - When you deliver your youtube video via
https://youtu.be/jyElDp98HdIyour test which checks that the embeded video is rendered in the view will fail because your test server doesn't use https
Solution
Let your lin...
Get Moving With Angular 1.2 Animation and Animate.css
Motion is quickly becoming one of the most important emerging techniques in building a quality user experience on the web. Angular 1.2, currently in release candidate form, provides an overhaul of Angular's animation system and makes it spectacularly easy to bring your interface to life.
International Address Fields in Web Forms :: UXmatters
Advice for address forms that work with address structures from multiple countries.
Enable NewRelic monitoring [for Rails] on specific hosts only
If you need to enable NewRelic monitoring on certain machines within the same Rails environment, a simple solution is to utilize the respective hostnames of you machines.
For example, if you have 8 application servers (e.g. app1.example.com, app2.example.com, ...) and want to enable NewRelic on app1 and app2 only, utilize those steps to do so:
- Put the attached file into your config directory (
config/custom_new_relic_configuration.rb). - Specify on which hosts NewRelic should be enabled (see
NEWRELIC_HOSTSconstant and list ...
A simpler default controller implementation
Rails has always included a scaffold script that generates a default controller implementation for you. Unfortunately that generated controller is unnecessarily verbose.
When we take over Rails projects from other teams, we often find that controllers are the unloved child, where annoying glue code has been paved over and over again, negotiating between request and model using implicit and convoluted protocols.
We prefer a different approach. We believe that among all the classes in a Rails project, controllers are some of the hardest to...
How to not repeat yourself in Cucumber scenarios
It is good programming practice to Don't Repeat Yourself (or DRY). In Ruby on Rails we keep our code DRY by sharing behavior by using inheritance, modules, traits or partials.
When you reuse behavior you want to reuse tests as well. You are probably already reusing examples in unit tests. Unfortunately it is much harder to reuse code when writing integration tests with Cucumber, where you need to...
Implementing social media "like" buttons: Everything you never wanted to know
So you client has asked you to implement a row of buttons to like the URL on Facebook, Twitter and Google+. Here are some things you should know about this.
0. Security considerations
Each "like" button is implemented by including a Javascript on your site. This means you are running fucking remote code on your page. You are giving Facebook, Twitter and Google+ full permission to e. g. copy user cookies. Check with your client if she is cool with that. Also note that if you're site is suggesting security by operating under HTTPS ...
RailsPanel chrome extension
Chrome extension that shows all info from your rails log (like parameters, response times, view rendering times, DB requests) inside a chrome panel.
Rails 3/4: How to add routes for specs only
If you want to have routes that are only available in tests (e.g. for testing obscure redirects), you can use the with_routing helper -- but that one destroys existing routes which may break a specs that require them to work.
To keep both "regular" and test routes, do this:
class MyApplicationController < ActionController::Base
def show
render text: 'Welcome to my application'
end
end
test_routes = Proc.new do
get '/my_application' => 'my_application#show'
end
Rails.application.routes.ev...
You don't need each, collect or select in Coffeescript
Working with lists in Javascript is painful because the native Array class is so poorly designed.
One way to reduce the pain is to to use Underscore.js's functions like _.each, _.map or _.select, which unfortunately clutters your code with awkward calls to the _ helper.
Fortunately when you use CoffeeScript you don't need any of that. CoffeeScript has a very versatile for keyword that can do anything that each, collect or select can do. Enjoy!
each
f...
PostgreSQL cheat sheet for MySQL lamers
So you're switching to PostgreSQL from MySQL? Here is some help...
General hints on PostgreSQL
-
\?opens the command overview -
\dlists things:\dulists users,\dtlists tables etc
Command comparison
| Description | MySQL command | PostgreSQL equivalent |
|---|---|---|
| Connect to the database | mysql -u $USERNAME -p |
sudo -u postgres psql |
| Show databases | SHOW DATABASES; | \l[ist] |
| Use/Connect to a database named 'some_database' | USE some_database; | \c some_dat... |
Disable text-transforms in Selenium tests
Using text-transform: uppercase - especially on form labels - can cause you serious headaches in Selenium tests. Sometimes the web driver will see the uppercase text, sometimes it won't, and umlauts will be a problem as well.
Simply disable it in tests, by
-
adding a body class for tests
%body{'data-environment' => Rails.env} -
overriding the transforms
[data-environment="test"] * text-transform: none !important
List of Compass Mixins
Since we are migrating from our homegrown mixins.sass and helpers.sass to Compass, here is a list of all the mixins provided by Compass.
Compiling Javascript template functions with the asset pipeline
The asset pipeline (which is actually backed by sprockets) has a nice feature where templates ending in .jst are compiled into Javascript template functions. These templates can be rendered by calling JST['path/to/template'](template: 'variables'):
<!-- templates/hello.jst.ejs -->
<div>Hello, <span><%= name %></span>!</div>
// application.js
//= require templates/hello
$("#hello").html(JST["templates/hello"]({ name: "Sam" }));
Whatever is in the <% ... %> is evaluated in Javascript...
Getting rid of space between inline-block elements
When two elements with display: inline-block are sitting next to each other, whitespace between becomes a space character.
Solutions, in decreasing order of awesomeness:
- Don't have whitespace between two elements! See Whitespace Removal in Haml if you're using Haml.
- Don't use
inline-block. Use floating elements instead (don't forget to clear them!). - Try to compensate for the space with a negative margin. Unfortunately you will never be able to negate ...
Font Awesome: List of Unicode glyphs and HTML entities
A list of FontAwesome icons in the form of copyable Unicode characters or HTML entities.
You might prefer to use FontAwesome by simply typing out these characters instead of using CSS classes. Of course you need to then give the containing element as style:
font-family: FontAwesome
Nested controller routes (Rails 2 and 3)
In order to keep the controllers directory tidy, we recently started to namespace controllers. With the :controller option you can tell Rails which controller to use for a path or resource. For nested resources, Rails will determine the view path from this option, too.
That means the following code in routes.rb …
resources :users do
resource :profile, controller: 'users/profiles' #[1]
end
… makes Rails expect the following directory structure:
app/
controllers/
users/
profiles_controller.rb
users_control...
Rails: Output helpers for migrations
When you're writing migrations that do more than changing tables (like, modify many records) you may want some output. In Rails > 3.1 you have two methods at hand: announce and say_with_time.
In the migration:
class AddUserToken < ActiveRecord::Migration
class User < ActiveRecod::Base; end
def up
add_column :users, :token, :string
announce "now generating tokens"
User.find_in_batches do |users|
say_with_time "For users ##{users.first.id} to ##{users.last.id}" do
users.each do |user|
...
Font sizing with rem - Snook.ca
CSS3 comes with new unit rem. It works like em but it is always relative to the <html> element instead of the parent element.
rem units are supported by all browsers and IE9+.