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...
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 ...
Embed Font Awesome icons from your CSS
An annoying part of using font icons is that the icons usually need to live in the DOM. This is a step back from the time when we defined raster icons with background-image, in the CSS.
It doesn't have to be that way.
Copy the attached file font-awesome-sass.css.sass to your assets (we recommend /vendor/asset-libs/font-awesome-sass).
You can now use Font Awesome icons from your Sass files:
@import font-awesome-sass
...
Ruby constant lookup: The good, the bad and the ugly
In Ruby, classes and modules are called constants. This card explains how Ruby resolves the meaning of a constant.
The good
E. g. in the following example, Array could mean either Foo::Array or simply Array:
class Foo
def list
Array.new
end
end
What Ruby does here is to see if the name Array makes sense inside of Foo::, and if that fails, resolves it to ::Array (without a namespace).
The bad
This is relevant for old Ruby versions. Ruby 2.5+ removes top-level constant lookup whi...
Ruby: How to measure code execution time in an IRB or Rails console
Modern IRB has time measurement built in.
measure # Enable
measure :off # Disable
Custom
Should your version of IRB not offer this feature, you can measure manually. Paste this method into your console:
def time(&block) puts Benchmark.measure(&block) end
Now time { Some.lengthy_task } will behave similar to the bash time command. Of course you can do much more with the Benchmark object than just putsing it – adapt to your needs.
Spreewald 0.8.0 brings a file attachment step
# Attach a file
#
# Example:
#
# Company.new.logo = File.new…
#
# Given the file "…" was attached as logo to the company above
#
#
# Example:
#
# class Gallery
# has_many :images, :as => :owner
# end
#
# class Image
# belongs_to :owner, polymorphic: true
# end
#
# # so container = Image.new; container.file = File.new… , container.owner = object
#
# Given the file "…" was attached as Image/file to the company above
#
#
# Example:
#
# Set updated_at with
#
# Given … above at "2011-11-11 11:11"
#
howto fix spreewald issue „database configuration does not specify adapter (ActiveRecord::AdapterNotSpecified)“
This error occurs when you already have a database.yml which defines the database for the cucumber environment instead of test. (Spreewald database.sample.yml has changed)
Fix
Change cucumber to test in your databse.yml
test: # <---
adapter: mysql2
database: spreewald_test
encoding: utf8
host: localhost
username: root
password: password
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...
Legacy docs for Font Awesome 3.2.1
Font Awesome 4 has renamed all icons. What the fuck.
Check the attached link for an icon list for the old Font Awesome 3.2.1.
Note
The following icons are listed on the linked page but may not exist in your vendored font:
icon-adn
icon-align
icon-ambulance
icon-anchor
icon-android
icon-angle
icon-apple
icon-archive
icon-arrow
icon-ban
icon-bar
icon-beer
icon-bitbucket
icon-btc
icon-bug
icon-building
icon-bullseye
icon-caret
icon-chevron
icon-circle
icon-cny
icon-code
icon-coffee
icon-col...
safe_cookies is now in public beta
We proudly release our safe_cookies middleware into public beta and just published it on Github.
Features are:
- make all application cookies
secureandHttpOnly(keeping them from being sent over HTTP and protecting them from Javascript) - rewrite all client cookies once, making them
secureandHttpOnly - notification if a request has unregistered cookies (no unsecure cookie will slip by)
- ability to ignore external cookies, like
__utmaand other tracking cookies - easy configurat...
Spreewald 0.6.7 "follow link in email"-step won't match backslashes any longer
When you build a link for an email body like this
body = "Please click the following link"
body << "http://posts/130\n\n"
body << "Members:"
...
then updating Spreewald to >=0.6.7 will be able to parse it correctly.
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...
Geordi: Choose your firefox version for cuc
Geordi 0.16+ supports running selenium tests with project-specific firefox versions.
Just update the gem. It will still default to using the old 5.0.1 firefox. If you want another one, add a file .firefox-version to your project, containing your preferred version.
geordi cucumber will prompt (and guide) you to install the given version. You can delete any old installation sitting in /opt/firefox-for-selenium if you have one.
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 ...
Enable CSRF protection in Javascript tests
You might not know that Rails disables CSRF protection in tests. This means that if you accidentally forget to send the CSRF token for non-GET requests, your tests will be green even though your application is completely broken (a failed CSRF check usually logs out the user). Rails probably does this because CSRF protection sort of requires Javascript.
You want to enable CSRF protection in Cucumber scenarios that can speak Javascript. To do so, copy the a...
Cucumber: Detect if the current Capybara driver supports Javascript
Copy the attached file to features/support. This gets you a convenience method:
Capybara.javascript_test?
Is true for Selenium, capybara-webkit, Poltergeist and a custom driver called :chrome (which we sometimes like to use for Selenium+Chrome).
Similar sounding but completely different card: Detect if a Javascript is running under Selenium WebDriver (with Rails)
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
Understanding AngularJS service types
Angular comes with different types of services. Each one with its own use cases.
All of these services are singletons. You probably want to use Factory all the time.
Provider
- is the parent of all other services (except
constant) - can be configured using `app.config(function(Provider) { ...})
- a little complex
Factory
- simpler than Provider, but without configuration
- definition: `app.factory('name', someFunction)
-
someFunctionis called when thenameservice is instantiated and should return an object
Se...
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...
Capybara: Trigger requests with custom request method
Preface: Normally, you would not need this in integrations tests (probably that's why it is so hard to achieve), because it is no actual "integration testing". If you use this step, know what you are doing.
Destroying a record with Capybara is not as easy as calling visit user_path(user, method: :delete), because RackTest's visit can only perform GET requests.
With this step you can destroy a records using either Selenium or RackTest. Ex...
Consul 0.10.0 allows multiple power mappings for nested resources
Consul 0.10.0 now allows multiple power mappings for nested resources.
When using nested resources you probably want two power
checks and method mappings: One for the parent resource, another for the child resource.
Say you have the following routes:
resources :clients do
resources :notes
end
And the following power definitions:
class Power
...
power :clients do
Client.active if si...
RSpec: Where to put custom matchers and other support code
Custom matchers are a useful RSpec feature which you can use to DRY up repetitive expectations in your specs. Unfortunately the default directory structure generated by rspec-rails has no obvious place to put custom matchers or other support code.
I recommend storing them like this:
spec/support/database_cleaner.rb
spec/support/devise.rb
spec/support/factory_bot.rb
spec/support/vcr.rb
spec/support/matchers/be_allowed_access.rb
s...
RSpec: Where to put shared example groups
Shared example groups are a useful RSpec feature. Unfortunately the default directory structure generated by rspec-rails has no obvious place to put them.
I recommend storing them like this:
spec/models/shared_examples/foo.rb
spec/models/shared_examples/bar.rb
spec/models/shared_examples/baz.rb
spec/controllers/shared_examples/foo.rb
spec/controllers/shared_examples/bar.rb
spec/controllers/shared_examples/baz.rb
To ma...
Rails: Disable options of a select field
Simply give the select helper an option :disabled, passing either a single value or an array. You need to specify the option's value, not its text.
= form.select :country, Address.countries_for_select, :include_blank => true, :disabled => ['disabled-value1', 'disabled-value-2']
Also see Cucumber: Check if a select field contains a disabled option on how to test this.