Skip to content

Shell

Web Dev roles

Now that I’m looking for a new role in web development, here’re some thoughts on the types of organisations I’ve worked with over the years.

I’ve worked in a fair few different environments over the years, from corporate to agency and freelance. Each unique, with their own set of business and organisational challenges–not just the technical site of things–and their own solutions for those challenges.

I’ve had a few fairly long stints in corporate (or corporate-light) environments covering for almost a decade of dev time. I honed skills in process, standards, requirements gathering. All solid take-aways that are part of every project I’ve worked on since. As a sometimes-freelancer on the side, the most frustrating aspect of these larger organisations has sometimes been speed of delivery. Even within the framework of Agile process, once a project is rolling, pragmatism quickly wains, change is not really encouraged, and they often roll and roll for a long time. Meanwhile, this business moves fast. Blink and the flavour of the week technology is… what is that thing? As a freelancer, you often own the technology stack and delivery. Because you own the agency of change, you can change. Experimentation is built in, if you let it.

For a subsequent role, I quite deliberately approached a digital agency. I wanted to step outside those somewhat walled environments.

I was lucky enough to step into a lead role at a lovely digital agency in Leith. It was everything I needed: a fluid environment of fast moving projects (for the most), each project a new opportunity to improve on approach and technology and apply Agile techniques, introduce standards and work with fantastic clients.

Teamwork is everything when deadlines and looming and the client is eager.

Aside from that great portfolio of clients (the good, bad, and ugly, but always something to learn) and technology stacks, the biggest take-away from working in an agency environment was the team. I’ve worked with some brilliant people over the years, but for the first time I discovered the teamwork sweet-spot: cross-discipline, client focused, delivery focused and pragmatic. Teamwork is everything when deadlines and looming and the client is eager. The trend to compartmentalise, to specialise too far–something I saw time and again in larger companies–always felt somewhat broken. A developer is not only a developer. A designer is not only a designer.

So, the logical next question is: would I take a role corporate environment again? The answer is: of course. The chance to take the learning’s from digital agency work back into that sort of environment also also attractive.

So here I am again, after 3 amazing years, looking for a change.

So here I am again, after 3 amazing years, looking for a change. It appears many larger companies have learned some of the above and run “internal startups”, perhaps a best-of-both-worlds, and attractive. Edinburgh has a fantastic start-up scene too. I’ve been really lucky over the past week to meet some fantastic teams across the city and it’s exciting. It’s refreshing.

Lets see where this goes.

Looking for a web developer? My LinkedIn profile is here.

Visual regression testing with Wraith

I’ve had a play with this before, but new machine, new set-up, this time I’ll document it…

First, what is Visual Regression Testing?

Simply, the visual comparison of two versions of a page, and highlighting any differences. It’s spot the difference for web folks.

It’s important to note this compliments other testing, catching the sort of difference easily missed in QA and by functional testing (be that in in CI or elsewhere). It also still requires someone to actually look and the output. Humans are significantly better at spotting things that are wrong, but they first need to be presented with the possibility that something could be wrong.

Okay, what is Wraith?

Wraith is a tool created by the BBC for automating some aspects visual regression testing.

Given two domains, it can compare pages between those domains. Wraith will highlight differences between pages (for example, a page on your local dev or pre-prod environment and a production environment) and save these as a screenshot for you to manually check. It will also flag unexpected percentage of difference, indicating if you have a potential problem.

Screenshot of Wraith output
Wraith output
Wraith output screenshot
Wraith visual output screenshot

Installing Wraith

  • Install HomeBrew. This is will take all the pain away. HomeBrew is a package manager for macOS and saves you having to mess around with installation paths and version management.
  • Install ImageMagick. This is required by Wraith to generate screenshots for comparison. From a terminal:
brew install imagemagick
  • Intall PhantomJS. This is a headless web browser that will load your site
brew install phantomjs
  • Install Wraith. Wraith itself is a Ruby package, and this assumes you have Ruby installed. Ruby ships with macOS, so we’re good to go:
gem install wraith

Now we have all the bits we need to run Wraith, we need to configure it to run.

You could run wraith setup but I prefer a hand-crafted config. You can save this into a config.yaml folder in your project, or wherever you’re doing CI testing. It should be pretty self-explanatory. Here’s the config for one one my sites:

browser: "phantomjs"
domains:
  current:  "https://shellbryson.com"
  dev:   "http://localhost:3001"
paths:
  home:     /
screen_widths:
  - 320
  - 600x768
  - 768
  - 1024
  - 1280
before_capture:
directory: 'wraith'
fuzz: '20%'
Default: 0
threshold: 5
  template: 'slideshow_template'
  thumb_width:  200
  thumb_height: 200
mode: diffs_first

On my particular setup, I have a dev copy running on port 3001 of my local Mac. This could be set to wherever your test environments live (CI environment, for example).

Running Wraith

As we installed a global ruby gem for Wraith and global prerequisites via Homebrew, you can run Wraith from anywhere on your system. It doesn’t have to be in your project folder.

Note: You may actually want to avoid committing your Wraith configuration to your project as it could expose testing URLs and other setup that you don’t want public.

  • Run Wraith with our configuration
wraith capture ./configs/capture.yaml

Wraith terminal screenshot

Wraith terminal screenshot

  • Wraith will provide a summary and will generate a series of screenshots. These can be found (in my case) in ./wraith/home/. These contain screenshots of each URL, a thumbnail, and a 3rd file containing the differences between URL.
  • Wraith also generates a gallery of ./wraith/gallery.html

In my setup I ran Wraith from my project folder, so Wraith’s gallery was served along with that on port 3001

Wraith gallery screenshot

References

Wraith documentation

Personal site refresh and BrowserSync gotcha

This sketch never made it into Sketch App…

After the experiments with branding earlier this week, it was about time I gave my ‘business card’ site at shellbryson.com a lick of paint. Didn’t want anything showy. Just a nice landing page for my main domain that leads off to various places I squirrel stuff.

It’s hand-crafted with no frameworks with SCSS, and a custom grunt job to glue it all together. While grunt has been somewhat superseded by other (“better”) task runners, it’s still dirt simple to put something together that’ll compile your SCSS on the fly and give a live-view (via BrowserSync) in a browser as you’re building. The latter I find essential when building more traditional projects.

The code for this project can be found in github.

Screenshot of shellbryson.com version 1.0
I guess I’m happy with this as a version 1.0.

Dev notes: BrowserSync failing to do anything via Grunt.

Had an interesting issue with BrowserSync and Watch tasks. BrowserSync was refusing to refresh (or even load). Turns out that the task order in Grunt matters a lot when it comes to BrowserSync. Any watch tasks must happen after BrowserSync or it can just silently fail.

Working example:

grunt.registerTask('default', [], () => {
 grunt.loadNpmTasks('grunt-browser-sync');
 grunt.loadNpmTasks('grunt-contrib-watch');
 grunt.task.run('browserSync', 'version', 'styles', 'watch');
});

Personal branding experiments

I’m having a lot of fun working on a personal brand at the moment. Part in due for being back on the market for a new front end role, but also because it has been ages since I got to dig into some design work for me.

But then again, I’m my own worst client. I knew I wanted something tactile, something that hinted at development, design and my nickname (origins decades old, don’t ask), something that would work well online and print. Tough getting all that into something simple.

After much sketching, pondering Pinterest boards, and staring bleakly at empty PhotoShop artboards, it was folding a paper plane for my daughter that inspired the design I’m happiest with.

An image of tiles demonstrating different logo treatments
I think “4b” works best

Then came the iterations, testing out business card and web layouts, but I’m pretty pleased with the results so far.

A stylised letter S

  • A chevron (think </> code)
  • A hint of an “S”.
  • Could be a physical foldable thing
  • Simple and geometric, lending itself for fun animations
  • …and lots of reusable elements.

 

 

 

Which is all fine on paper (uh, in Sketch app), but it needs to work online. Given the nice geometric nature of the elements of the logo, it’s not too hard. This would’ve been a nightmare if I’d started out in PhotoShop, and I’m a big fan of doing as much as possible in Sketch these days.

  • Sketch app (Mac)
  • Sketch ‘edit’ symbols to get corner coordinates for each triangle >
  • Manually enter coordinates as clip masks in CSS (CodePen)

And finally, we can play with it in CodePen. This gives me loads of room for adding nice folding animations (a task for another evening).

Adding a CDN to WordPress

A CDN can significantly improve site performance. I’ve home-spun a few in the past (using spare servers), but that’s not going to give the distributed performance boost of a truly localised CDN service.

Step 1

We’ll be using KeyCDN for our CDN services. There are plenty of these services to choose from, but keyCDN offers a relatively inexpensive service and decent geolocation, and more importantly the ability to use on-demand SSL certificates for free via LetsEncrypt—which is critical if your site is already using SSL and you want to make use of a CDN.

First we create a Zone, and point this our primary domain (mydomain.com). Ensure that SSL is enabled. No site should be running without SSL these days.

Now we can create a Zone Alias, which configures the subdomain we’ll be using on our site. Once created, this will provide us with the “real” domain (mydomain-7b2b.kxcdn.com). We’ll need to add this to a CNAME record in our DNS in the next step.

Note, on KeyCDN, you can generate an SSL certificate for your domain (for free) by selecting LetsEncrypt from the SSL options.

Step 2, creating a subdomain

To avoid mixed content warnings (and future-proof our setup) we need to use SSL on our CDN because our main domain is also using SSL. We enabled SSL in step 1, but to make use of this, we’ll need to create an alias for it on our own DNS.

Via your DNS provider (in this case, Digital Ocean), create a new CNAME record cdn.mydomain.com and point it at mydomain-7b2b.kxcdn.com

It’ll take a while for this to propagate before the CDN will correctly be associated with your domain.

Step 3, configure WordPress

We’ll be using the WordPress Super Cache plugin here to do the work for us. Basically, it can rewrite the URLs of any assets you upload to WordPress to our newly created CDN.

All you have to do is enter the subdomain in the CDN tab.

Now we can test that it’s all working. Browse to the site and take a look at the networking tools. We should see our assets now being served via cdn.mydomain.com.

Animating SVG (CSS vs. GreenSock GSAP)

Inline SVGs (not those loaded as images) can be styled like any other collection of DOM elements. But there appear to be a few limitations. Primarily, due to the way transforms (coordinates) are handled within SVG relative positioning is hard.

I really wanted to explore animating SVG elements with purse CSS, and to an extent this went swimmingly… until I started trying to animate the SVGs child elements.

CSS animation on CodePen 

Screenshot of CSS animated SVG
Animated via CSS (CodePen)

As the coordinates inside an SVG are relative to the grouped elements inside the SVG definition (rather than the HTML DOM, or the window), when we start trying to position child elements I quickly hit a wall.

GreenSock

Defeated (for now) I picked up the oddly named GreenSock animation library (GSAP). It’s shockingly easy to get up and running. Once we have the GSAP library referenced in our code,

var myElementHandle = new TweenMax.to(
  document.getElementById("mySVGElement"), 160, 
    rotation: 360, transformOrigin:"center center", ease: Linear.easeNone, repeat:-1
  }
);

GSAP animation on CodePen

Screenshot of SVG animated with GSAP
Animated via GSAP (CodePen)

Now we can target anything we want using names or class and GSAP will do the heavy lifting. A passive function of GSAP is how it handles changing animations (for example, triggering a new animation on mouseover on an element that is already animating). GSAP will blend any active animations to ensure a smooth interaction—something not possible in CSS.

As we’re relying on JS, it’s really easy for us to start manipulating our SVG in other ways too, such as generating new elements and handling interaction. For example, I added a couple of experimental functions:

// Creates a new svg element [id] attached to [parentID]
function createSVGElement(id, cssClass, x, y, parentID) {
  var svg = document.createElementNS("http://www.w3.org/2000/svg","circle");
  svg.setAttributeNS(null, "class", cssClass);
  document.getElementById(parentID).appendChild(svg);
}

And this…

// Creates a clone of svg element [id] as [newID]
function cloneSVG(id, newID, x, y, parentID) {
  var node = document.getElementById(id);
  var newNode = node.cloneNode("true");
  newNode.id = newID;
  newNode.setAttributeNS(null, "cx", x);
  newNode.setAttributeNS(null, "cy", y);
  document.getElementById(parentID).appendChild(newNode);
}

Dev Notes

I’ve used SVG shapes generated from Sketch here, so had to make sure any elements / groups I wanted to target with JS had names. Sketch will slugify the names if you don’t add something JS-safe yourself.

Reference: