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...
The Plight of Pinocchio: JavaScript's quest to become a real language - opensoul.org
Great presentation about writing Javascript like you write everything else: Well-structured and tested.
JavaScript is no longer a toy language. Many of our applications can’t function without it. If we are going to use JavaScript to do real things, we need to treat it like a real language, adopting the same practices we use with real languages.
This framework agnostic talk takes a serious look at how we develop JavaScript applications. Despite its prototypical nature, good object-oriented programming principles are still relevant. The...
Ruby: Debugging a method's source location and code
Access the Method
object
Dead simple: Get the method object and ask for its owner:
"foo".method(:upcase)
# => #<Method: String#upcase>
"foo".method(:upcase).owner
# => String
Look up a method's source location
Ruby 1.9 adds a method Method#source_location
that returns file and line number where that method is defined.
class Example; def method() end; end
# => nil
Example.new.method(:method).source_location
# => ["(irb)", 11]
"foo".method(:upcase).source_location
# => nil # String#upcase is a native method...
Fix „rvm no such file to load -- openssl“ or "rvm no such file to load -- zlib"
For example if you use rvm and get this message:
ERROR: Loading command: install (LoadError)
no such file to load -- zlib
ERROR: While executing gem ... (NameError)
uninitialized constant Gem::Commands::InstallCommand
You've installed your ruby without having all required libraries.
I don't know why there isn't a Warning message if you install a ruby with rvm and didn't have libraries like openssl and zlib.
To fix this you can execute this:
#to show the requirements for your system
rvm requireme...
Ruby 1.9 or Ruby 2.0 do not allow using shortcut blocks for private methods
Consider this class:
class Foo
private
def test
puts "Hello"
end
end
While you can say create a block to call that method (using ampersand and colon) on Ruby 1.8, ...
1.8.7 > Foo.new.tap(&:test)
Hello
=> #<Foo:0x1e253c8>
... you cannot do that on Ruby 1.9 or 2.0:
1.9.3 > Foo.new.tap(&:test)
NoMethodError: private method `test' called for #<Foo:0x00000001e8c258>
^
2.0.0 > Foo.new.tap(&:test)
NoMethodError: private method `test' called for #<Foo:0x000000027bc738...
MySQL: How to create columns like "bigint" or "longtext" in Rails migrations, and what :limit means for column migrations
Rails understands a :limit
options when you create columns in a migration. Its meaning depends on the column type, and sometimes the supplied value.
The documentation states that :limit
sets the column length to the number of characters for string
and text
columns, and to the number of bytes for binary
and integer
columns.
Using it
This is nice since you may want a bigint
column to store really long numbers in it. You can just create it by ...
How to copy your „Google Chrome“ or „Chromium“ profile without creating an online account
Google Chrome saves your profile data in ~/.config/google-chrome
.
To transfer the profile to for example a system you have setup freshly do following steps:
- make a copy of
~/.config/google-chrome
- install google-chrome
- restore your backuped profile to
~/.config/google-chrome
- launch google-chrome
(Replace google-chrome by chromium-browser if you use chromium-browser)
ActiveRecord: count vs size vs length on associations
TL;DR: You should generally use #size
to count associated records.
size
- Counts already loaded elements
- If the association is not loaded, falls back to a
COUNT
query
count
- If a counter cache is set up, returns the cached value
- Issues a
COUNT
query else
Caveats
- If you trigger a
COUNT
query for an association of an an unsaved record, Rails will try to load all children where the foreign keyIS NULL
. This is not what you want. To prevent this behavior, you can useunsaved_record.association.to_a.size
. - `c...
Loading dumps via SSH, unpacking and sourcing them, all with a progress bar
Here is a hacky way to load dumps directly from the source server, without fully copying them over and extracting them first.
It may break horribly for you. This is the dark side of the force.
- Install pipe viewer, if you don't have it already:
sudo apt-get install pv
- Know the location of the dump file on the remote server. We'll use
/mnt/dumps/my_project.dump.bz2
in the example below. - Find out the size of the (bzipped) file in by...
MySQL will not use indexes if you query the wrong data type
When MySQL refuses to use your index, there's a number of things that you may be doing wrong. One of them might be conditions with improper data types.
An example
For example, let's assume you have a users
table with an email
field (varchar
) which is indexed.
MySQL will use the index when your query is well-formed:
mysql> EXPLAIN SELECT * FROM users WHERE email = 'foo@example.com';
+----+-------------+-------+-------+----------------------+----------------------+---------+-------+------+-------+
| id | select_type |...
CSS: Combining different length units with calc()
calc()
lets you mix CSS units. Ever wanted to give an element "the container's width minus 20px on each side"? Here you go:
.foo {
width: calc(100% - (20px * 2));
}
When using Sass, you need to interpolate Sass expressions:
$margin: 20px * 2
.foo
width: calc(100% - #{$margin})
Supported by all modern browsers and IE9+.
How to fix: Session hash does not get updated when using "merge!"
tl;dr: Do not use merge!
for session hashes. Use update
instead.
Outline
Let's assume you're modifying the Rails session. For simplicity, let's also assume your session is empty when you start (same effect when there is data):
# In our example, we're in a Rack middleware
request = Rack::Request.new(env)
request.session.merge! :hello => 'Universe'
request.session
=> {}
Even worse: When you inspect your request.session
like above (e.g. in a debugger shell, o...
Test xpath expressions in your browser
Safari & Chrome
Use $x()
in your console:
$x('//span') # selects all span elements
Firefox
There's an add-on.
JavaScript: Comparing objects or arrays for equality (not reference)
JavaScript has no built-in functions to compare two objects or arrays for equality of their contained values.
If your project uses Lodash or Underscore.js, you can use _.isEqual()
:
_.isEqual([1, 2], [2, 3]) // => false
_.isEqual([1, 2], [1, 2]) // => true
If your project already uses Unpoly you may also use up.util.isEqual()
in the same way:
up.util.isEqual([1, 2], [2, 3]) // => false
up.util.isEqual([1, 2], [1, 2]) // => true
If you are wri...
MongoMapper for Rails 2 on Ruby 1.9
MongoMapper is a MongoDB adapter for Ruby. We've forked it so it works for Rails 2.3.x applications running on Ruby 1.9. [1]
makandra/mongomapper
is based on the "official" rails2
branch [2] which contains commits that were added after 0.8.6 was released. Tests are fully passing on our fork for Ruby 1.8.7, REE, and Ruby 1.9.3.
To use it, add this to your Gemfile
:
gem 'mongo_mapper', :git => 'git://github.com/makandra/mongomapper.git', :branch => 'rails2'
...
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-...
How to silence UTF-8 warnings on Rails 2.3 with Ruby 1.9
Rails 2.3.16+ on Ruby 1.9 causes warnings like this:
.../gems/activesupport-2.3.17/lib/active_support/core_ext/string/output_safety.rb:22: warning: regexp match /.../n against to UTF-8 string
Many thanks to grosser for supplying a monkey-patch for Rails 2.3 (Commit f93e3f0ec3 fixed it for Rails 3). Just put it into config/initializers/
to make those warnings go away.
Since we're using RSpec on mos...
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...
How to fix: Microphone recording levels are too quiet (or get lowered automatically)
If others on a call (Skype, SIP, ...) can not hear you loud enough, your volume levels are probably too low. Also, Skype may be changing your mixer levels.
Set a proper recording volume
- Open your mixer software (run
pavucontrol
). - Switch to input devices.
- If you have more than one recording device, find the correct one.
- Make a test call to a colleague that can tell you if it's too loud or too quiet.
- Drag the volume slider for your input device to an adequate level -- for me, 75% (-7.46dB) work fine. 100% is usually way to...
Fix warning "already initialized constant Mocha" with Rails 3.2
You either have an old version of Mocha and an edge version of Rails 3.2, or you have a new version of Mocha and an old version of Rails. The best solution is to update Mocha to the latest version and switch to Rails edge.
If you are using shoulda-matchers
or another gem that locks Mocha to an old version, you are out of luck.
More info with many other workarounds that you do not want to use can be found here. A hack to work around this case is to add the following file to lib/mocha/setup.rb
:...
Rails SQL Injection Examples
This page lists many query methods and options in ActiveRecord which do not sanitize raw SQL arguments and are not intended to be called with unsafe user input. Careless use of these methods can open up code to SQL Injection exploits. The examples here do not include SQL injection from known CVEs and are not vulnerabilites themselves, only potential misuses of the methods.
Please use this list as a guide of what not to do.
rsl/stringex · GitHub
Stringex is a gem that offers some extensions to Ruby's String class. Ruby 1.9 compatible, and knows its way around unicode and fancy characters.
Examples for stringex's String#to_url
method:
# A simple prelude
"simple English".to_url => "simple-english"
"it's nothing at all".to_url => "its-nothing-at-all"
"rock & roll".to_url => "rock-and-roll"
# Let's show off
"$12 worth of Ruby power".to_url => "12-dollars-worth-of-ruby-power"
"10% off if you act now".to_url => "10-percent-off-if-you-act-now"
# You do...