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...
Spreewald: When using `patiently do`, don't reuse existing variable names
Spreewald's patiently
repeats the given block again and again until it either passes or times out.
Be careful to give patiently
a block that can actually be repeated. E.g. the following block can not be repeated:
Given /^the field "(.*?)" is empty$/ do |field|
patiently do
field = find_field(field)
field.text.should be_blank
end
end
The reason the above code will fa...
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...
How to make Rational#to_s return strings without denominator 1 again
The way Rational#to_s
works on Ruby has changed from Ruby 1.9 on. Here is how to get the old behavior back.
You may want this for things where Rationals are being used, like when subtracting Date
objects from one another.
What's happening?
Converting a Rational
to a String
usually does something like this:
1.8.7 > Rational(2, 3).to_s
=> "2/3"
1.9.3 > Rational(2, 3).to_s
=> "2/3"
2.0.0 > Rational(2, 3).to_s
=> "2/3"
However, when you have a Rational
that simplifies to an integer, you will only get a St...
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.
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...
What's in a View? A look at the alternatives
Great look at the tradeoffs between progressive enhancement with jQuery or similiar, vs. client-side views.
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...
Initiate SSL secured TCP connections to remote services
Establishing a TCP connection to a SSL secured remote service is not possible using telnet
or nc
.
Though, you can use openssl
for that:
openssl s_client -connect www.makandra.com:443
Chart.js - a promising JavaScript charting library with MIT-license
Chart.js seems to be a good alternative to Google's Chart API and other commercial chart drawing libraries.
- good looking charts
- canvas based (means less memory consumptive, but no interactivity out of the box)
- highly configurable
- good API and documentation
- just 4.5 kilobytes
- MIT license
- Browser support: all browsers supporting the canvas element (for IE8 and below, use the polyfill as describes in the [chart.js documentation...
Comparing Rails' flash hashes will not respect their internal lists of used entries
Rails flashes (FlashHash
) track a list of used keys, which is not respected when comparing flash hashes.
This does not concern you under most circumstances.
Basics
When ActionController
picks up a flash object, it will call the #sweep
method once; that method checks the list of used flash entries and deletes those. All other entries are flagged as used. This means they will be deleted on the next request, but are still be available for rendering during the current request.
Fun facts: When redirecting, this does not happen. Also,...
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...
Tips And Tricks For Print Style Sheets
Smashing Magazine lists some handy tricks for print style sheets, all with CSS:
- Expand External Links For Print
- Print QR Codes For Easy URL References
- Use CSS filters to improve the result of printed graphics (i.e. images with transparent parts)
- Use your DevTools to preview the print styles in your browser
Interactive generator for gradients, borders, noise textures and box shadows
CSSmatic lets you play around with four rather complex CSS stylings and gives you CSS or SASS code to use your result right away.
- Gradients
- Borders
- Noise textures – offers a texture download
- Box shadows
Browser Hacks: CSS Rules to Target Specific Browsers And Versions
The linked site lists a wealth of CSS hacks that let you apply styles to just that one browser. You should be using this mostly for fixing browser issues and not give up on creating solid styles.
About progamming with Multi-Touch, Touch- and Mouse-Events in the webbrowser
Since there are more and more touch-capable devices out there, as a web-developer it becomes more and more important to know how to deal with touch events next to mouse events and how you you can combine both worlds (mouse and touch interaction).
Here's a quick introduction to (multi-)touch browser events and an advanced article that deals with touch and mouse events and how they can be combined.
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...
Different behavior for BigDecimal#floor in Ruby 1.8 and Ruby 1.9
Ruby 1.8 (supplied by Rails' ActiveSupport)
>> BigDecimal.new("0.1").floor.class
=> BigDecimal
Ruby 1.9 (supplied by Ruby 1.9 itself)
>> BigDecimal.new("0.1").floor.class
=> Fixnum
In fact, Float#floor
has changed from Ruby1.8 to Ruby 1.9 which is used by BigDecimal#floor
internally.
Attached initializer backports Ruby 1.9 behavior to Ruby 1.8.
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)
How to: Ruby heredoc without interpolation
When you use heredoc, string interpolation is enabled by default:
x = "Universe"
<<-MESSAGE
Hello #{x}
MESSAGE
# => "Hello Universe"
This may be impractical sometimes. To avoid interpolation in heredoc strings, simply enclose your heredoc marker with single quotes:
x = "Universe"
<<-'MESSAGE'
Hello #{x}
MESSAGE
# => "Hello #{x}"
That will make the string behave like a single-quoted string, so sequences like \n
wil...