RSpec: automatic creation of VCR cassettes
This RailsCast demonstrated a very convenient method to activate VCR for a spec by simply tagging it with :vcr.
For RSpec3 the code looks almost the same with a few minor changes. If you have the vcr and webmock gems installed, simply include:
# spec/support/vcr.rb
VCR.configure do |c|
c.cassette_library_dir = Rails.root.join("spec", "vcr")
c.hook_into :webmock
end
RSpec.configure do |c|
c.around(:each, :vcr) do |example|
name = example.metadata[:full_descripti...
Working on the Linux command line: How to use bookmarks for directories
Bookmarks for directories will be most helpful if you are forced to work in deeply nested projects. Then it's really helpful!
This makes use of the CDPATH variable. Similar to the PATH variable, which holds the list of directories which are searched for executables, CDPATH contains the list of directories that are available for cd. Besides the current directory (.), you can add others to that.
The trick is to add a directory for bookmarks to CDPATH.
First, create the directory with: mkdir ~/.bookmarks.
Then add the followin...
Working on the Linux command line: How to efficiently navigate up
With cd .. you can navigate one directory up from the one you are at now. If you use that a lot, consider some handy aliases.
Add the following lines to your ~/.bashrc:
alias ..="cd .."
alias ...="cd ../.."
alias ....="cd ../../.."
alias .....="cd ../../../.."
alias ......="cd ../../../../.."
you can add even more aliases, but I usually loose track after too many levels and just jump to the directly directly, e.g. using its absolute path or its bookmark (see [this card](https://makandracards.com/makandra/504947-working-on-the-li...
Unpoly 2: Don't try to download files through AJAX requests
Rails has the handy controller method send_file which lets us download files easily. We can decide whether the file should be downloaded (disposition: 'attachment') or shown in the browser (disposition: 'inline'). The default is disposition: 'attachment'.
Downloading files will not work when you are calling the controller action from an AJAX request. The browser will try to render the file and insert it in the DOM, which is never what you want.
Unpoly 2
Unpoly (sin...
You should probably load your JavaScript with <script defer>
It is generally discouraged to load your JavaScript by a <script src> tag in the <head>:
<head>
<script src="app.js"></script>
</head>
The reason is that a <script src> tag will pause the DOM parser until the script has loaded and executed. This will delay the browser's first contentful paint.
A much better default is to load your scripts with a <script src defer> tag:
<head>
<script src="app.js" defer></script>
</head>
A deferred script has many useful properties:
- I...
Bookmarklet to facilitate generating new git branches for PivotalTracker Stories
This bookmarklet grabs a PivotalTracker story title, transforms it into a valid git branch name and automatically prepends your initials and an optional abbreviation (for better tab completion). It will output the following formats:
If you cancel the first dialog or confirm it without entering text:
git checkout -b kw/178298638-card-320-state-machines
If you enter an abbreviation (e.g. stm in this case):
git checkout -b kw/stm/178298638-card-320-state-machines
How to set it up:
- in the attached file replace `YOUR_INITI...
Headless Chrome: Changing the Accept-Language header is not possible
It seems like changing the HTTP_ACCEPT_LANGUAGE is not possible for a headless chrome.
- On Ubuntu the headless Chrome derives the Accept-Language from the operation system
- Adding the option
options.add_argument('--lang=de')to theCapybara::Selenium::Driverhas no effect - Adding the preference
options.add_preference('intl.accept_languages', 'de')to theCapybara::Selenium::Driverhas only effects if the--headlessoption is skipped (see bug ticket #775911) - Cha...
Modern HTTP Status codes for redirecting
Formerly 301 (Moved Permanently) and 302 (Found) were used for redirecting. Browsers did implement them in different ways, so since HTTP 1.1 there are some new status codes which allow for finer distinctions.
The interesting part is how non-GET requests are handled by the redirect. It is preferrable to use the newer status code to avoid unexpected behavior.
303 See Other
The response to the request can be found under anot...
How to avoid raising RestClient exceptions for 4xx or 5xx results
When using RestClient to make an HTTP request, it will raise an exception when receiving a non-successful response.
HTTP status codes like 422 or 403 might be totally expected when talking to APIs, so plastering your code with rescue RestClient::Exception or similar can feel annoying.
It may not be intuitive, but the readme says you can also pass a block to methods like RestClient.get or RestClient::Request.execute. In that case, RestClient will not raise ...
How to checkout submodules in Gitlab CI
Accessing other repositories in Gitlab CI is not straight forward, since the access rights of the current pipeline might not be sufficient enough.
One approach is to use project access tokens and clone the repositories via HTTPS.
-
Create a project access token for all submodules you want to have access to with the setting
read_repository - Add the secrets as environment variable to the main project you want to have access to submodules:
- Protected
false...
- Protected
NVM: How to automatically switch version when changing directories
The Node Version Manager allows installing multiple NodeJS versions and switching between them.
By default, it does not automatically switch versions when entering a directory that holds a .nvmrc file.
The project's readme document offers a bash function which calls nvm use after each cd. In fact, it replaces cd in your bash.
I did not want to do that, but instead use the $PROMPT_COMMAND feature. So here is my take on it.
Note that it is much shorter, it probably does a f...
Ruby: Fixing strings with invalid encoding and converting to UTF-8
When dealing with external data sources, you may have to deal with improperly encoded strings.
While you should prefer deciding on a single encoding with the data-providing party, you can not always force that on external sources.
It gets worse when you receive data with encoding declaration that does not reliably fit the accompanying string bytes.
Here is a Ruby class that helps converting such strings to a proper encoding.
Note that it tries several approaches of changing the encoding. **This is not a silver bullet and may or may not work...
Pre-releasing a Ruby gem
When a Ruby version gem has a letter in its version number, it is considered a pre-release:
1.0.0.rc12.3.0.alpha23.0.0.beta34.0.0.pre.rc2
Even if a pre-release gem has the highest version number, it is never installed unless the user explictily requested the version:
gem install foobar --version="=2.3.0.alpha2"
Also bundle update will never update a stable version to a pre-release version unless the user explicitly requests it in the Gemfile:
gem 'foobar', '=2.3.0.alpha2'
A note on Semanti...
When does Webpacker compile?
Webpack builds can take a long time, so we only want to compile when needed.
This card shows what will cause Webpacker (the Rails/Webpack integration) to compile your assets.
When you run a dev server
While development it is recommended to boot a webpack dev server using bin/webpack-dev-server.
The dev server compiles once when booted. When you access your page on localhost before the initial compilation, the page may load without assets.
The ...
Limiting GitLab CI runner to specific branches or events
Use rules to include or exclude jobs in pipelines.
Rules are evaluated in order until the first match. When a match is found, the job is either included or excluded from the pipeline, depending on the configuration. The job can also have certain attributes added to it.
rules replaces only/except and they can’t be used together in the same job. If you configure one job to use both keywords, the linter returns a key may not be used with rules error.
GitLab 12.3 introduced rules. You can use them in your .gitlab-ci.yml in your proj...
Bundler: Packaging gems into the git repository (offline installation)
Installing gems on a server that has no access to the internet (especially rubygems.org) requires to bundle the gems into the repository itself. This requires to adjust the bundle config in the repository.
- Execute the following commands to configure bundler:
bundle config set --local path vendor
bundle config set --local disable_shared_gems true
Note
For Bundler < 2 you have to omit the "set":
bundle config --local name value.
See here: [https://bundler.io/v1.17/man/bundle-config.1.html](https://bundler.io/v1.17/man...
Delivering Carrierwave attachments to authorized users only
Preparation
To attach files to your records, you will need a new database column representing the filename of the file. To do this, add a new migration (rails g migration <name>) with the following content:
class AddAttachmentToNotes < ActiveRecord::Migration[6.0]
def change
add_column :notes, :attachment, :string
end
end
Don't forget to rename the class and change the column details to fit your purpose. Run it.
1) Deliver attachments through Rails
The first way is to store your Carrierwave attachments not ...
Capybara: Preventing headless Chrome from freezing your test suite
We prefer to run our end-to-end tests with headless Chrome. While it's a very stable solution overall, we sometimes see the headless Chrome process freeze (or the Capybara driver losing connection, we're not sure).
The effect is that your test suite suddenly stops progressing without an error. You will eventually see an error after a long timeout but until then it will seem that your suite is frozen. If you're also using [capybara-screenshot](https:/...
Capybara: Preventing server errors from failing your test
When your Rails application server raises error, Capybara will fail your test when it clears the session after the last step. The effect is a test that passes all steps, but fails anyway.
Capybara's behavior will help you to detect and fix errors in your application code. However, sometimes your application will explode with an error outside your control. Two examples:
- A JavaScript library references a source map in its build, but forgets to package the source map
- CarrierWave cleans up an upload or cache file after the record was delet...
RSpec: How to test the content of a flash message in a request spec
The ActionDispatch module of Rails gives you the helper method flash to access the flash messages in a response.
describe PostsController, type: :request do
describe 'update' do
it 'shows a success message on update' do
post_record = create(:post)
put "/posts/#{post_record.id}"
# Same as @request.flash[:alert]
expect(flash[:alert]).to eq('Post updated successfully.')
end
end
end
makandra/capybara-lockstep
capybara-lockstep can help you with flaky end-to-end tests:
This Ruby gem synchronizes Capybara commands with client-side JavaScript and AJAX requests. This greatly improves the stability of a full-stack integration test suite, even if that suite has timing issues.
Webmock < 3.12.1 cannot handle IPv6 addresses correctly
We had the issue, that a VCR spec failed, after updating CarrierWave from version 0.11.0 to 1.3.2.
In this version, CarrierWave uses the gem SsrfFilter, which retrieves the IP addresses for the given hostname and replaces the hostname in the requested url with one of them.
It works with IPv4 addresses, but not with IPv6 addresses, because WebMock cannot handle those correctly:
uri = "#{protocol}://...
Making ZSH the default shell on Ubuntu 20.04
ZSH is an alternative command line shell that includes some features like spelling correction, cd automation, better theme, and plugin support. You can replace Bash with ZSH like following:
sudo apt-get install zsh
Setting ZSH as default login shell
sudo usermod -s /usr/bin/zsh $(whoami)
Opening a new terminal window will show you a dialog where you can configure your initial ZSH config (Option 2 recommended).
Afterwards you can install the plugin manager Oh-My-ZSH and select a prop...
CarrierWave: Default Configuration and Suggested Changes
CarrierWave comes with a set of default configuration options which make sense in most cases. However, you should review these defaults and adjust for your project wherever necessary.
You will also find suggestions on what to change below.
Understanding the default configuration
Here is the current default config for version 2:
config.permissions = 0644
config.directory_permissions = 0755
config.storage_engines = {
:f...