How to open a new tab with Selenium
Until recently, you could open a new tab via window.open
when using execute_script
in Selenium tests. It no longer works in Chrome (will show a "popup blocked" notification).
This is because browsers usually block window.open
unless the user interacted with an element for security reasons. I am not sure why it did work via Selenium before.
Here is an approach that will insert a link into the page, and have Selenium click it:
path = "/your/path/here"
id = "helper_#{SecureRandom.hex(8)}"
execute_script <<-JAVASCRIPT
...
Using regular expressions in JavaScript
Regular expressions in Javascript are represented by a RegExp
object. There also is a regex literal as in many other languages: /regex/
. However, they are used slightly differently.
Regex literal
- Usage:
/foo+/
- Shorthand for creating a regular expression object
RegExp() object
- Usage:
RegExp("foo+")
ornew RegExp("foo+")
- No surrounding slashes required (they're the literal markers)
- Since the argument is a string, backslashes need to be escaped as well:
RegExp("\\d+")
Gotchas
- Regex objects [never eq...
RSpec & Devise: How to sign in users in request specs
You know that Devise offers RSpec test helpers for controller specs. However, in request specs, they will not work.
Here is a solution for request specs, adapted from the Devise wiki. We will simply use Warden's test helpers -- you probably already load them for your Cucumber tests.
First, we define sign_in
and sign_out
methods. These will behave just like ...
Defining and calling lambdas or procs (Ruby)
Ruby has the class Proc
which encapsulates a "block of code". There are 2 "flavors" of Procs
:
- Those with "block semantics", called
blocks
or confusingly sometimes alsoprocs
- Those with "method semantics", called
lambdas
lambdas
They behave like Ruby method definitions:
- They are strict about their arguments.
-
return
means "exit thelambda
"
How to define a lambda
-
With the
lambda
keywordtest = lambda do |arg| puts arg end
-
With the lambda literal
->
(since Ruby 1.9.1)
...
Stop writing "require 'spec_helper'" in every spec
Simply add this to your .rspec
instead:
--require spec_helper
If you are on rspec >= 3 and use a rails_helper.rb
require this instead of the spec_helper
:
--require rails_helper
If you are using parallel_tests
and this is not working for you, .rspec
might be ignored. Try using a .rspec_parallel
file.
Case Study: Analyzing Web Font Performance
Table of contents of the linked article:
What are Web Fonts?
- Advantages of Web Fonts
- Disadvantages of Web Fonts
- Fallback Fonts
- CSS3 @font Declaration Example
- Fallback Font Example
- Render Blocking and Critical Rendering Path
- FOIT
Optimizing Web Font Delivery Further
- Prioritize Based On Browser Support
- Choose Only Styles You Need
- Character Sets
- Host Fonts Locally or Prefetch
- Store in LocalStorage with Base64 Encoding
- Another Method
Web Font Pe...
Test your application's e-mail spam scoring with mail-tester.com
You can use mail-tester.com to check your application's e-mails for issues that might cause e-mails to be classified as spam.
They provide a one-time e-mail addresses that you can use to sign up etc. You can then check for scoring results of SpamAssassin and other potential issues.
You don't need to hit 10/10. Something around 9/10 is perfectly fine.
Note:
- For password-protected staging sites you will get an error for links that can not be resolved. This is fine, simply check production once available.
- ...
Lazy-loading images
Note
This card does not reflect the current state of lazy loading technologies. The native lazy attribute could be used, which is supported by all major browsers since 2022.
Since images are magnitudes larger in file size than text (HTML, CSS, Javascript) is, loading the images of a large web page takes a significant amount of the total load time. When your internet connection is good, this is usually not an issue. However, users with limited bandwidth (i.e. on mobile) need to mine their data budget...
How to run a small web server (one-liner)
Sometimes you just want to have a small web server that serves files to test something.
Serve the current directory
On Ruby 1.9.2+ you can do the following (".
" for current directory).
ruby -run -ehttpd . -p8000
Python 2.x offers a similar way.
python -m SimpleHTTPServer 8000 .
This is the same way with Python 3.x
python -m http.server
In both cases your web server is single-threaded and will block when large files are being downloaded from you.
WEBrick also offers [a simple way](https://stackoverflow.com/quest...
Gemspecs must not list the same gem as both runtime and development dependency
When you're developing a gem, never list the same dependency as both runtime and development dependency in your .gemspec
.
So don't do this:
spec.add_dependency 'activesupport'
spec.add_development_dependency 'activesupport', '~> 2.3'
If you do this, your gemspec will not validate and modern versions of Bundler will silently ignore it. This leads to errors like:
Could not find your-gem-0.1.2 in any of the sources
What to do instead
If you want to freeze a different version of a dependency for your t...
Reverse-proxying web applications with nginx
While you can use Apache as a reverse proxy, it tries to be too smart. Try nginx instead, it's much simpler to set up.
After struggling with Apache for quite a while, since I simply could not make it pass through the Digest Authentication of my target host (that I proxied to), I switched to nginx. Here is what I did.
-
Have nginx
sudo apt-get install nginx
-
Define your nginx config, e.g. at
/etc/nginx/conf.d/reverse-proxy.conf
:server { listen 127.0.0.1; location /...
How to split up a git commit
Quick steps
-
git rebase -i
-> mark your commit withedit
-
git reset HEAD~
(remove the marked commit, but keep its changes) - Make several commits (optionally setting the previous author manually)
git rebase --continue
Detailed instructions
Basically, you will review the last n
commits and stop at the splittable commit. Then you'll undo that commit and put its changes into new commits at your liking.
-
Review commits (
rebase
)git rebase -i HEAD~3 # or git rebase -i origin/master
...
AngularJS: How to force Content-Type on GET and DELETE requests
While you usually do not need a Content-Type
on GET request (which have a blank body), an external API may still force you to send one.
Angular's $http
service will strip that header when the request data (body) is blank. [1] This is possibly a misconception of RFC2616.
Here is how to send GET requests with a Content-Type
header in Angular.
Example
Consider this request:
$http({ me...
Configure RSpec to raise an error when stubbing a non-existing method
You can configure RSpec 3.3+ to raise an error when attempting to stub or mock a non-existing method. We strongly recommend to do this as non-verified stubs are a footgun.
You can enable this behavior by adding the following to your spec_helper.rb
:
RSpec.configure do |config|
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
This will also replace stub_existing
from our rspec_candy.
About Ruby's conversion method pairs
Ruby has a set of methods to convert an object to another representation. Most of them come in explicit and implicit flavor.
explicit | implicit |
---|---|
to_a |
to_ary |
to_h |
to_hash |
to_s |
to_str |
to_i |
to_int |
There may be even more.
Don't name your methods like the implicit version (most prominently to_hash
) but the like the explicit one.
Explicit conversion
Explicit conversion happens when requesting it, e.g. with the splat opera...
Sending TCP keepalives in Ruby
When you make a simple TCP connection to a remote server (like telnet
), your client won't normally notice when the connection is unexpectly severed on the remote side. E.g. if someone would disconnect a network cable from the server you're connected to, no client would notice. It would simply look like nothing is being sent.
You can detect remote connection loss by configuring your client socket to send TCP keepalive signals after some period of inactivity. If those signals are not acknowledged by the other side, your client will terminat...
Fix "subprocess installed post-removal script returned error exit status ..." when installing/removing/updating a package with apt
If you get an error like:
subprocess installed post-removal script returned error exit status 78
when installing/removing/updating a package with apt you should check the postinst
, postrm
, prerm
, ... script in /var/lib/dpkg/info/
.
For example in my case I had a problem when removing varnish:
Removing varnish (4.0.3-2~trusty) ...
dpkg: error processing package varnish (--remove):
subprocess installed post-removal script returned error exit status 78
Errors were encountered while processing:
varnish
So I checked ...
Test downstream bandwidth of Internet connection
You want to test your 1GE or 10GE internet uplink? We needed to ensure we have full 10GE to the backbone for a customer project.
Using netcat
To test whether we can achieve the bandwidth internally, you can use netcat and dd like this:
On your first server: nc -v -l 55333 > /dev/null
On your second server: dd if=/dev/zero bs=1024K count=5000 | nc -v $remote_ip 55333
You should see some output like this:
user@xxx:~ % dd if=/dev/zero bs=1024K count=5000 | nc -v removed 55333
Connection to 91.250.95.249 55333 port [...
How to remove properties of ActiveRecord scopes
When dealing with AR scopes, you can remove conditions, order, etc by using the unscope
method.
It is available on Rails 4+.
Examples
Consider an exemplary User
class as follows. For the examples below, we will use a scope that applies all its constraints.
class User < ActiveRecord::Base
scope :active, -> { where(locked: false) }
scope :admins, -> { where(role: 'admin') }
scope :ordered, -> { order(:name) }
end
users = User.active.admins.ordered
^
SELECT "users".* FROM "users" WHERE "use...
A case for Redactor
Redactor is yet another WYSIWYG editor. It definitely has its weak points, but I want to point out that it has clear strengths, too.
Pro
- Simple and beautiful interface.
- Outstandingly organized source code. Have never seen a JS library that was this structured.
- Clear, comprehensive and searchable API documentation. Filled with code examples.
- Easily customizable: specify toolbar buttons, pass various callbacks, etc.
- Features a collection of great [plugins](ht...
PostgreSQL: How to add/remove/modify array values (and how to replace 1 value with multiple values)
PostgreSQL's array data type is pretty useful, but manipulating values of arrays can be awkward because of its syntax.
Consider the following users
table which each example below will start from:
name | topics |
---|---|
Alice | {cats,dogs} |
Bob | {llamas} |
(PostgreSQL uses curly braces to represent arrays, true story.)
Adding values
Use the array_cat
function, or the ||
operator.
These calls will add the values "cats" and "mice" to use...
Keeping web applications fast
Our applications not only need to be functional, they need to be fast.
But, to quote Donald Knuth,
premature optimization is the root of all evil (or at least most of it) in programming
The reasoning is that you should not waste your time optimizing code where it does not even matter. However, I believe there are some kinds of optimizations you should do right away, because
- they are either obvious and easy
- or they are very hard to do optimize later
This is an attempt to list some of those things:
On the server
...
Heads up: Ruby implicitly converts a hash to keyword arguments
When a method has keyword arguments, Ruby offers implicit conversion of a Hash
argument into keyword arguments. This conversion is performed by calling to_hash
on the last argument to that method, before assigning optional arguments. If to_hash
returns an instance of Hash
, the hash is taken as keyword arguments to that method.
Iss...
Ruby: Do not mix optional and keyword arguments
Writing ruby methods that accept both optional and keyword arguments is dangerous and should be avoided. This confusing behavior will be deprecated in Ruby 2.7 and removed in Ruby 3, but right now you need to know about the following caveats.
Consider the following method
# DO NOT DO THIS
def colored_p(object = nil, color: 'red')
switch_color_to(color)
puts object.inspect
end
colored_p(['an array']) # ['an array'] (in red)
colored_p({ a: 'hash' }, color: 'blue') # {:a=>'hash'} (in blue)
colored_p({ a: 'ha...