I’ve been improving our Development and Staging environments with more realistic seed data and hit an unexpected issue.

We previously used Faker and Markov chains to generate filler content whenever staging was reset, but the results were unrealistic. Users found it hard to see past the gibberish and focus on the features under test.

Now we use Polo to extract a portion of our Production database, remove any pII, and build a realistic seed for testing, development and feature demos.

The only problem is that the seed is too realistic.

If an administrator is regularly using multiple environments they may lose track of whether they’re about to make a harmless change on Staging or nuke a paying customer on Production. I’ve heard of more than one company losing data because someone didn’t realise they were on a live environment when they pressed “Delete”.

We also started to get red-alert bug reports from staff swearing that Production was misbehaving only to find they were furiously hitting refresh on a test environment.

When the content between Staging and Production is almost indistinguishable users are left with only the address bar to orient themselves, and that’s not a particularly friendly solution.

Our original fix was to colour-code the UIs (blue for Production, green for Staging), but this had several shortcomings. A colour-code is too abstract and doesn’t scale as the number of environments increases. It also doesn’t work on the public-facing site where the colour scheme has to stay as realistic as the content.

The second approach was to add a floating bar that proclaimed the environment, but users tend to focus on the middle of the screen and become blind to superfluous page elements.

What I wanted was something that is always visible, not too intrusive, understandable, and didn’t need configuration when a new environment is added.

Hopefully no-one can miss that
module ApplicationHelper
  def environment_watermark(css_selector = 'body', _opts = {})
    return '' if Rails.env.production? || !opts[:force]

    watermark = Rails.env.to_s
    text_tag = tag.text(watermark, transform: 'rotate(45)',
                                   x: 10,
                                   y: 10,
                                   fill: 'rgba(0,0,0,0.1)',
                                   'font-size': 20)
    svg_tag = tag.svg(text_tag, height: '150px',
                                width: '150px',
                                version: '1.1',
                                xmlns: 'http://www.w3.org/2000/svg')
    data_url = "data:image/svg+xml;utf8,#{svg_tag}"
      (css_selector + "{ background-image:url('#{data_url}')!important;}").html_safe

Calling environment_watermark in the layout renders a repeating SVG background image that’s subtle enough to not intrude, but omnipresent enough to be unmissable. On Production’s admin engine we force: true to show the background, but otherwise that’s the one environment that stays unmarked.