MySQL: Careful when using database locks in transactions
We tend to use database transactions as a magic bullet to get rid of all our concurrency problems. When things get really bad, we might even throw in some locking mechanism, but then are usually done with it.
Unfortunately, transactions semantics in databases are actually very complicated, and chances are, your making some incorrect assumptions.
The MySQL innodb engine actually has [four different modes](ht...
Consul 0.9 lets you optimize records checks
Consul 0.9 comes with many new features to optimize powers that only check access to a given record. e.g. Power.current.post?(Post.last)
. See below for details.
Powers that only check a given object
Sometimes it is not convenient to define powers as a collection. Sometimes you only want to store a method that
checks whether a given object is accessible.
To do so, simply define a power that ends in a question mark:
class Power
...
power :upd...
ActionView::Template::Error (dump format error for symbol(0x6d))
I recently encountered the error above when I was running selenium tests.
Thanks to a post on stackoverflow I found out that clearing all files in tmp/cache in my project folder made the issue go away.
Switch to a recently opened tab with Cucumber
Similar to closing an opened browser window, spreewald now supports the I switch to the new browser tab
step.
Info
See the Spreewald README for more cool features.
You can use it to test links that were opened with a link_to(..., :target => '_blank')
link or other ways that create new tabs or windows.
Important
This only works with
Selenium
...
Riding Rails: Rails 4.0: Final version released!
Rails 4.0 is finally ready after a thorough process of betas and release candidates. It's an amazing new version packed with new goodies and farewells to old features past their expiration date.
Upgrading Rails 2 from 2.3.8 through 2.3.18 to Rails LTS
This card shows how to upgrade a Rails 2 application from Rails 2.3.8 through every single patch level up to 2.3.18, and then, hopefully, Rails LTS.
2.3.8 to 2.3.9
This release has many minor changes and fixes to prepare your application for Rails 3.
Step-by-step upgrade instructions:
- Upgrade
rails
gem - Change your
environment.rb
so it saysRAILS_GEM_VERSION = '2.3.9'
- Change your ...
Before you make a merge request: Checklist for common mistakes
Merge requests are often rejected for similar reasons.
To avoid this, before you send a merge request, please confirm that your code ...
- has been reviewed by yourself beforehand
- fulfills every requirement defined as an acceptance criterion
- does not have any log or debugging statements like
console.log(...)
,byebug
etc. - has green tests
- has tests...
marcandre/backports · GitHub
Essential backports that enable many of the nice features of Ruby 1.8.7 up to 2.0.0 for earlier versions.
How to clear cookies in Capybara tests (both Selenium and Rack::Test)
Capybara drivers will usually delete all cookies after each scenario. If you need to lose cookie data in the middle of a scenario, you can do this:
browser = Capybara.current_session.driver.browser
if browser.respond_to?(:clear_cookies)
# Rack::MockSession
browser.clear_cookies
elsif browser.respond_to?(:manage) and browser.manage.respond_to?(:delete_all_cookies)
# Selenium::WebDriver
browser.manage.delete_all_cookies
else
raise "Don't know how to clear cookies. Weird driver?"
end
Inherit without Single-Table-Inheritance (STI) in ActiveRecord
You have multiple options:
- Just don't have a
type
column. All STI magic will be disabled automatically. - If you have a
type
column but want to use it for something else (WAT?), you can setself.inheritance_column = :_non_existing_column
in the class definition - (Untested) In the parent class, set
self.abstract_class = true
This technique is useful to implement form models / presenters, where you want all the goodness of Ac...
How to find out if you are in Cucumber or in RSpec
Sometimes you need a piece of code to do something different for specs than for features. If you don't have separate environments, you can't check your Rails.env
.
I managed to distinguish between specs and features by asking Capybara
.
Note that this only works when you do not use Capybara in specs.
if defined?(Capybara) and Capybara.respond_to?(:current_driver)
# you're in a Cucumber scenario
else
# you're probably in a spec
end
You could omit the defined?(Capybara)
condition, if you are sure that Capybara
...
Git: How to show only filenames for a diff
When you want to do a git diff
but do not care about the full diff and just want to know which files changed, use the --name-only
switch:
$ git diff --name-only
app/controllers/sessions_controller.rb
app/models/user.rb
features/sign_in.feature
To include some brief information about changed lines, use the --stat
switch:
$ git diff --stat
app/controllers/sessions_controller.rb | 8 +-
app/models/user.rb | 30 ++++
features/sign_in.feature | 136 +++++++++++++++++
T...
Ruby: What extend and include do
All Rubyists should be familiar with the common definitions for include and extend. You include a module to add instance methods to a class and extend to add class methods. Unfortunately, this common definition isn’t entirely accurate. It fails to explain why we use instance.extend(Module) to add methods to an instance. Shouldn’t it be instance.include(Module)? To figure this out we’re going to start by discussing where methods are stored.
- include: Adds methods from the provided Module to the object
- extend: Calls include on the single...
parallel_tests: Disable parallel run for tagged scenarios
Note: This technique is confusing and slows down your test suite.
Copy the attached code to features/support
. This gets you a new Cucumber tag @no_parallel
which ensures that the tagged scenario does not run in parallel with other scenarios that are tagged with @no_parallel
. Other scenarios not tagged will @no_parallel
can still run in parallel with the tagged test. Please read the previous sentence again.
This can help when multiple test processes that access a single resource that is hard to shar...
YAML syntax compared with Ruby syntax
yaml4r is a juxtaposition of yaml documents and their Ruby couterpart. Thus, it does a great job as YAML-doc, e.g. when writing Rails locale files. Did you know that ...
-
<<
is a merge key (similar to&
in SASS) - there are variables, called aliases. Definition:
&alias Some content
, usage:*alias
.
Caveats
Specifying a key twice does not merge the sub keys, but override the first definition, e.g.
de:
car: # overridden
door: Tür
...
How to set the user agent in tests
The User-Agent
HTTP header identifies the client and is sent by "regular" browsers, search engine crawlers, or other web client software.
Cucumber
In Rack::Test
, you can set your user agent like this on Capybara:
Given /^my user agent is "(.+)"$/ do |agent|
page.driver.browser.header('User-Agent', agent)
# Or, for older Capybaras:
# page.driver.header('User-Agent', agent)
end
For Selenium tests with Firefox, it seems you can set the general.useragent.override
profile setting to your preferred value. [See StackOver...
def vs. define_method
Ever wondered about the difference between def
and define_method
? Turns out there are three implicit contexts in Ruby. def
and define_method
differ in which one they use.
def
- Ruby keyword, starts a method definition
- Opens a new, isolated scope. Variables defined outside are not accessible inside and vice versa.
- Defines an instance method on the receiver (specified before the method name, e.g.
def object.foo
); implicit receiver is the default definee
The default definee is not self
and...
Test redirects to an external URL with Cucumber/Capybara
When a controller action redirects to an external URL (like http://somehost.com/some/path
) you will find that this is hard to test with Cucumber and Capybara:
- A non-Javascript Rack::Test scenario will just ignore the host and try to open
/some/path
in your local application - A Selenium test will actually follow the redirect, which you probably don't want either
There are two workarounds for this. You can use either, or a combination of both.
- Write a controller spec
Controller specs can test if a resp...
How to disable cookies in cucumber tests
Unfortunately, Capybara does not offer a switch to disable cookies in your test browser. However, you can work around that by using a tiny Rack middleware -- it works for both Selenium and non-Selenium tests.
Wouldn't it be nice to say something like this?
Given cookies are disabled
When I try to sign in
Then I should see "Can't sign you in. Please enable cookies."
You can! Put the code below into some place like lib/rack/cookie_stripper.rb
.
module Rack
class CookieStripper
ENABLED = false
...
Cucumber step to set cookies in your Capybara session
To set a cookie in your test browser for cucumber tests, you need to know which driver you are using. Use the step below according to your driver.
Rack::Test
Given /^I have a "([^\"]+)" cookie set to "([^\"]+)"$/ do |key, value|
headers = {}
Rack::Utils.set_cookie_header!(headers, key, value)
cookie_string = headers['Set-Cookie']
Capybara.current_session.driver.browser.set_cookie(cookie_string)
end
Note that Rack::Utils
is only used to find out the correct cookie header string (you don't want to generate it yours...
Capybara 0.3.9 Bug: Chaining .find to scope doesn't work
The following code doesn't work like expected:
page.find(css_selector).find(other_css_selector)
The second .find will search the whole dom instead of a scope.
Rumor has it this is fixed in Capybara 0.4.1.
Selenium: How to close another tab (popup)
If you open a pop-up window [1] in your Selenium tests and you want to close it, you can do this:
# Find our target window
handle = page.driver.find_window("My window title")
# Close it
page.driver.browser.switch_to.window(handle)
page.driver.browser.close
# Have the Selenium driver point to another window
last_handle = page.driver.browser.window_handles.last
page.driver.browser.switch_to.window(last_handle)
Mind these:
-
find_window
returns a window handle, which is something like `"{485fa8bd-fa99-...
Capturing signatures on a touch device
If you need to capture signatures on an IPad or similar device, you can use Thomas J Bradley's excellent Signature Pad plugin for jQuery.
To implement, just follow the steps on the Github page.
The form
If you have a model Signature
with name: string, signature: text
, you can use it with regular rails form like this:
- form_for @signature, :html => { :class => 'signature_form' } do |form|
%dl
%dt
= form...
Using CSS counters - CSS | MDN
Counters are an awesome CSS feature you didn't know about. It is supported in all browsers and IE8+.
CSS counters are an implementation of Automatic counters and numbering in CSS 2.1. The value of a counter is manipulated through the use of counter-reset and counter-increment and is displayed on a page using the counter() or counters() function of the content property.