Digital Marketing & Communications

We've seen 1s and 0s you wouldn't believe

Posts By: Iris Faraway

Visual regression testing with Wraith

📥  Design, Development, Tools

Last week I talked about how we chose Wraith as our visual regression testing tool.

After lots of discovery and preparation, we were now ready to get our first real tests up and running.

Screenshot of tests in Wraith

Example of a failed test in Wraith. Differences are highlighted in blue – in this case, I've modified the summary slightly.

In this post, I'll go through how we run our tests locally and as part of our continuous integration process. But go make a cup of tea first, because this will be a long one...

(more…)

Choosing a visual regression testing tool

📥  Design, Development, Tools

We've recently been working on getting visual regression testing up and running for bath.ac.uk.

Back in October, Liam blogged about our earlier research into visual regression testing. But if you need a refresher...

Visual regression testing in a nutshell

Visual regression testing is a way of automatically checking webpages to catch any unwanted changes, or 'regressions', in the design.

These unwanted changes are a risk we run every time we modify the code for the design of the site. Sometimes a single tweak in one place can have unexpected consequences for another aspect of the design.

We could just eyeball lots of different pages to see if anything looks wrong, but this takes a lot of time, and there's always a chance of missing some tiny difference.

It would be much better to write some automated tests which take screenshots of the pages before and after we've modified our code, and then highlight any changes.

Changes are highlighted in blue. Oops, that shouldn't have moved.

Differences are highlighted in blue. Oops, that should not have moved.

Basically, it'll save us loads of time and keep bath.ac.uk looking great!

We were excited to crack on, but before we could get our tests up and running, we had some decisions to make.

Choosing a tool

There are a lot of different options out there for visual regression testing. We'd previously followed a tutorial using WebdriverCSS, but struggled to make the tests run consistently and generally found it a frustrating experience.

We decided to investigate alternatives. Our discovery process included:

  • reading any guides and documentation
  • checking the release history to see how well maintained it was
  • getting it running locally if possible
  • writing and running some basic tests

Some of the tools we looked at were:

And the winner is...

After doing the research and discussing the options with our designers and developers, we decided to go with Wraith.

We ain't afraid of this ghost

We ain't afraid of this ghost

Built by BBC News developers, Wraith has also been used by the Guardian and the Government Digital Service.

It's written in Ruby, our dev team's language of choice. The config and tests are written in YAML, which we felt was easier to work with than the alternatives (usually JSON or JavaScript). When we tested it out, it took less than an hour to install everything and write and run our first tests.

It also offered two options for running the tests – you can compare new screenshots to historical ones, or compare the same page across two different environments (for example, staging and production).

Deciding what to test

We'd chosen a tool, but we still needed to decide what to use it on.

Like many visual regression testing tools, Wraith allows you to test entire pages or individual elements.

Testing individual elements makes finding differences much more precise – otherwise one change high on the page can have a knock-on effect on everything below it. Having a comprehensive pattern library can make it even easier to test individual elements.

All of this sounded great, but our pattern library isn't in a testable format yet, and writing tests for individual elements is time-consuming.

We wanted to get up and running as quickly as possible, so we decided to test full-page screenshots of real pages in each content type. This will provide a solid level of coverage, and of course we can always keep improving our tests and making them more comprehensive.

We also had to decide what screen resolutions to test at. We checked our Google Analytics stats for 2016 and found the top 3 resolutions across desktop, mobile and tablet.

One size (1280 x 800) appeared in both desktop and tablet, so this left us with 8 sizes to test against – ranging from 1920 x 1080 all the way down to 320 x 568.

Next up: implementation

We now had a plan for writing and running our first real visual regression tests.

In my next post, I'll talk about the process of getting Wraith set up and fitting the tests into our workflow.

 

Making our Slackbot open source

📥  Development

Back in November, I blogged about writing a Slackbot for our team to provide editorial guidance on request.

We recently decided to make the bot open source. You can now see all the code on Github.

A very brief introduction to open source

'Open source' basically means making your project's code public so people can read and reuse it. This means everyone can use your code themselves if they want, or adapt it to make something new. They might even make their own contributions to your project.

Our team and our users benefit a lot from open-source projects, so it's something we're always keen to do ourselves. One of our digital principles is 'Work in the open', and open-sourcing code is a great way to do that.

We've shared several of our projects on the uniofbathdmc Github.com account, so this was an obvious new home for the bot.

Moving to a public Github repository

Until now, the Slackbot lived in a private repository on the University's Github Enterprise environment. On Github.com, if you want to copy code from one repository to another, you can easily fork it. But moving from Github Enterprise to Github.com is a little more complicated.

Before making any of the code public, I did a little bit of housekeeping, including:

  • adding a LICENSE file with details about the Apache license 2.0
  • updating the README to make the set-up instructions clearer for potential new users
  • reviewing the code and commit history to make sure we wouldn't expose anything that was confidential or a security risk

Once everything was in order, I created a new empty repository for our team's Github.com account.

The next step was to change the remote for my local version of the repository. This meant that any changes I made would be sent to the new repository instead.

Once the remote was updated, a quick git push in the command line uploaded the bot to the new repository. Hey presto, open sourcery!

Rewriting history

I opened up Chrome to look at the new repo on Github.com. All my files, commits and history were there, but all those commits were from my private Github Enterprise account.

That account doesn't exist on Github.com, so it looked like all the code had been written by the mysterious if243, with no indication of who that was. I decided to tweak this so all the commits came from my own Github.com account.

The git-filter-branch command allows you to modify your commit history. I used this to change all the authors and committers from my private account to my public one. As usual, StackOverflow was a big help.

One git push --force later, all the commits had been updated and the project history was much clearer.

The bot's open-source future

The bot is now open source, but that doesn't mean it's finished. Any more changes we make to the bot will be in our public repository. And now that the code is open to all, there's a much bigger opportunity for other people to get involved too.

This also gives us the chance to experiment with some cool tools which are available for free to open-source projects, like CircleCI and Hound.

It's a small offering, but it still feels nice to contribute to the open-source community that's given us so much.

 

A day in the life of a developer

📥  Development, Team

This is the first in a 'Day in the Life' series for the different roles in the Digital team. If you've ever wondered what our team gets up to on an average day, or what it's like to work in a particular digital discipline, read on.

Here's a typical day as a developer, based on what I did on a recent Monday.

What I spend much of my day looking at

What I spend much of my day looking at

I get in around 9am and immediately make a coffee before cracking on with some work. Our team plans our work in two-week segments called 'sprints', and this is the last day of one. I start reviewing the code for some recently finished work so we can try to get everything ready to be signed off at the end of the day.

At 9.45, our daily standup happens. Everyone in the Digital team stands in a circle and says:

  • the most important thing they did yesterday
  • the most important thing they'll do today
  • any blockers that might prevent them from doing that work

Standup only lasts about 10 minutes, but it means that everyone in the team knows what they're meant to be doing and what everyone else is working on.

After standup, I finish looking at the reviews. Everything looks good, so the stories are now ready for the Development Manager to look at and accept (or reject – but let's hope not).

Next I get together with a few other team members and do our fortnightly infrastructure review. We set aside an hour to make sure our documentation is up to date and identify any potential problems or upgrade work we need to do.

After a break for lunch, my afternoon is nice and clear. I spend the afternoon working on a new feature for the Content Publisher. 'Unpublishing' allows our editors to temporarily remove a page from the live site without deleting it entirely, so they can continue to make changes and republish it later if required. Having hours at a time to really get my head into a problem is one of my favourite parts of this job, and working on something our users will find helpful is always satisfying.

The day finishes with a retrospective about the completed sprint. Everyone in the build team shares what they thought went well during the sprint, as well as any issues they encountered. I really like our fortnightly retrospectives – they're a good way to wrap up a sprint, celebrate our successes and discuss ideas for making the next one even better.

So, that's what it's like to be a developer in the Digital team.

 

Adding a state machine to a Rails application

📥  Development

We recently implemented a state machine in the Content Publisher. While this isn't a change many people will notice, it does lay the foundation for further improvements which we hope will benefit our users.

This work also contributed to my ongoing education in computer science concepts and design patterns. Hopefully this post will share some of what I've learned.

Introduction to state machines

A state machine, or finite-state machine, is a computational model. It's designed to manage things which can be in one of several pre-defined states. Items can transition between states, but can only be in one state at a time.

A properly-implemented state machine can define:

  • what your states are
  • what things can do while they're in a certain state
  • when something is allowed to transition from one state to another
  • what happens when something transitions between states

A good example of what I mean by 'states' is what happens when you order a product online. Your order goes through several states: 'received', 'processing payment', 'packing', 'out for delivery', 'delivered', possibly even 'returned'.

While the state the order is in changes during the process, it will only ever be in one state at a time. The order can be in a 'packing' state or a 'delivered' state, but never both at the same time.

There are also rules about how the order moves between states – for example, your order won't move from 'delivered' back to 'packing'.

And different things can happen during the states. Maybe you can cancel your order when it's still in 'received' or 'processing payment', but not once it's in 'out for delivery'.

All these rules and processes are set through the state machine.

The state of states in the Content Publisher

States are a key part of the workflow in the Content Publisher. Content items can be in 3 states: 'draft', 'in review' and 'published'. All items start out in 'draft', but as our users work on them they progress on to

But we might want to add more in the future, like 'scheduled for publication' or 'archived'.

While the Content Publisher has states, and items can move between states, we don't manage these in the clearest way. The logic which controls which states items can be in is spread across the codebase, which makes it difficult to read or to modify.

We decided it was time to implement our own state machine.

State machines and Ruby

We could build a state machine ourselves, but there are so many popular state machine gems out there that we wanted to look at those first.

I started by checking Ruby Toolbox to see what the most popular state machine gems are. The top one is state_machine, but this is no longer maintained, making it a risky proposition.

The next most popular gem is AASM, short for 'acts as state machine'. AASM is well-maintained, with an active community and pretty good documentation – all important if we want to welcome it into our codebase.

I also looked into several other gems, including workflow and transitions. But AASM seemed the most promising, so I tested it out by building a prototype in a fresh Rails app.

AASM in action in our discovery prototype

AASM in action in our discovery prototype

The prototype confirmed that AASM ticked all our boxes. It was time to implement it properly.

Adding a state machine to the Content Publisher

The next step was to get AASM up and running in the Content Publisher to replace our existing functionality.

Implementing AASM was more complex here than in the prototype. This was mostly because we've been working on the Content Publisher for nearly two years and so had a lot of code to change.

This gave me a good opportunity to get more familiar with a broad range of our code – everything from role-based permissions to version control.

If you're thinking of using a state machine in a Rails application, I'd definitely recommend trying to put it in place as early as possible to minimise the amount of refactoring.

After many commits and an extensive review, we finally shipped to production on 16 January.

What comes next?

While our switch to AASM made no immediate difference to our end users, it does make our code better and more extensible.

We've now laid the foundation for adding new states or transitions, which could enable new features – like scheduling an item to publish later, or unpublishing a live item.

We'll be doing some more research into how we can improve our workflow, so keep an eye out for more changes in the coming months.

Progressive enhancement and team memberships

📥  Beta, Development

We recently shipped some changes to how we order team members in our Team Profile content type.

These improvements came in several stages, each building on the last, so this seemed like a good opportunity to talk about progressive enhancement.

What is progressive enhancement?

The Government Digital Service's service manual has a great explanation of progressive enhancement:

It’s based on the idea that you should start by making your page work with just HTML, and consider everything else an extra.

This is because the only part of a page that you can rely on to work is the HTML. If the HTML fails there’s no web page, so you should consider the rest optional.

We prefer this approach to immediately building a feature with all the extras (like JavaScript) and then trying to make it degrade gracefully (or just keeping our fingers crossed that it doesn't break).

Progressive enhancement is important for accessibility. By making sure your feature works with HTML alone, you can be more confident that your feature will work for people who are:

  • using assistive technologies
  • on slow or compromised connections
  • don't have JavaScript enabled for some other reason

Progressive enhancement is also well-suited to Agile, as you can start with the core functionality and then iterate.

Introduction to the feature

Users have two options when it comes to creating team profiles:

  • 'Create manually' – create a list of names and roles using Markdown
  • 'Select from Person Profiles' – add Person Profiles to the team to pull through the member's name, role, photo and other important information

When we first built the 'Select from Person Profiles' feature, users had no say over the order in which the team's members were listed on the page.

Members with the 'Leadership Profile' subtype were always listed first. All other members were then listed in alphabetical order. Our users reported that this wasn't ideal and it was often important that members be listed in a certain order. For example, the manager of a team should probably be listed first, even if they don't have a 'Leadership Profile'.

Adding the order with HTML

Our earlier version of the Team Profiles interface did have some JavaScript. Adding the order was complex enough that it was easier to strip out any existing JavaScript and go back to basics.

After some complicated data structure changes behind the scenes, we had a shiny new field called 'Order in team'.

Team members in the base implementation

Team members in the base implementation

Users could now specify the order by entering numbers into these fields. When they saved or published the page, members would appear in the order they'd chosen, both in the interface and on the page itself.

Saving the page also added more empty member dropdown menus, so users could add more members if they wanted to.

We now had the core functionality, even if there was still room for a bit of polish.

We shipped this version of the feature and then moved on to the enhancements.

Adding the magic with JavaScript

We had the essential behaviour of the feature, but there was still room to improve the user experience.

Now that we had a feature which worked with HTML only, we could add enhancements for any users who also had JavaScript enabled.

Our JavaScript addition did several things:

  • replaced the multiple dropdown menus with a single one, which adds new members to a list below
  • allowed users to drag and drop the members in the list into their desired order
  • hid the member order fields, but updated them behind the scenes whenever users rearranged the members through drag-and-drop
  • added a remove button for each member to take them off the list

These enhancements make it quicker for users to add, reorder and remove team members.

Team members with JavaScript enabled

Team members with JavaScript enabled

If the user doesn't have JavaScript enabled, none of these enhancements kick in, but the feature still works as before.

This means the Content Publisher can still be used by broad range of people, no matter which technology they're using.

What comes next?

We don't work with JavaScript nearly as often as we do Ruby. As such, our practices need a bit of work.

Because the JavaScript implementation changes the interface, this means inserting HTML into the page. Currently we store this HTML in the script itself, which is messy and difficult to read. It's probably time for us to get familiar with a JavaScript templating engine – Handlebars.js seems like a likely candidate.

Trying (and failing) to test the drag-and-drop behaviour in Capybara also revealed that we need a better way to handle feature tests and JavaScript. We've got some planned investigation into Poltergeist which will hopefully sort this out.

While neither of these changes will be apparent to users, it should make our development process smoother as we roll these sorts of JavaScript enhancements out to other parts of the Content Publisher.

 

Making a Slackbot for editorial guidance

📥  Development

In the Digital build team, we have two hours every Wednesday to work on our own personal development. I recently spent a few of these sessions making my own Slackbot.

A slack-what?

Slack is a messaging application designed for work teams. We've used it for several years now and found it an extremely useful communication tool – it's a great way to keep everyone in the loop while keeping our email inboxes relatively clear.

A Slackbot is a program that interacts with users through Slack. It can react to user input (like a user saying a certain command) or external input (like a trigger from another website to post a message in Slack).

Slack comes with its own bot, @slackbot, which responds to several default commands and has some customisation options.

Using @slackbot's reminder functionality

Using @slackbot's reminder functionality

Unsurprisingly, lots of other digital services have built their own bots to integrate with Slack. We use these to get notifications in Slack when something important happens, for example, if a team member starts a new story in Pivotal Tracker or a new version of Ruby is released.

This bot notifies everyone in the #beta channel when something deploys

This bot notifies everyone in the #beta channel when the Content Publisher deploys

Building my own Slackbot

The content team has written a lot of guidance for our lead publishers, from editorial style to using specific content types in the Content Publisher. We use this guidance a lot ourselves. I decided to create a bot that could make it easier to retrieve this guidance from the comfort of the Slack window.

I built my bot using Ruby. The slack-ruby-bot gem makes it really easy to get a basic bot up and running. After registering the bot with Slack and setting up an API token, I added it to a channel.

The bot responds to anyone who greets it with a cheery "Hi @username!" out of the box, but then it was up to me to add my own functionality.

Setting up a very basic Slackbot command

Setting up a very basic Slackbot command

We've had a lot of raging debates about our editorial style for bulleted lists, so inevitably this was my Slackbot's first new feature:

Not this again...

Not this again...

Getting variables from the user

It's also possible to build more complex features. Slackbots can get variables from user input (regular expressions come in handy here), so I added a feature that lets users request a particular guide.

I created a hash with the names of guides and their URLs. When the bot receives the command, it identifies the term provided by the user and checks the hash to see if there is a corresponding guide. If there is, it posts the URL for the guide in the channel.

Requesting guidance on using images

Requesting guidance on using images using the command 'rtm' (or 'read the manual')

This might save some time for users, but they still need to leave Slack to read the information. What if we want the bot to provide guidance directly in Slack?

Retrieving information from the web

Our editorial style guide is the longest, most detailed guidance we have for creating content on bath.ac.uk. Sometimes it can take a while to find what we're looking for. What if the bot could do it for us?

We could follow the same format as the guide search feature and just store all the information in the code. But our editorial style guide is constantly evolving, so this could quickly become out of date. And it'd be absolutely massive. It's better to have the bot to search the guide itself directly.

Nokogiri is a Ruby library for parsing HTML and XML documents. It's an incredibly useful tool for searching or processing the content of a webpage. I decided to use Nokogiri to search for and retrieve content in the editorial style guide.

Here's how the feature works:

  1. A Slack user requests content from the editorial style guide using the command "style guide for [search term]".
  2. The bot recognises the request and gets the search term.
  3. The bot uses Nokogiri to get the content of the editorial style guide from the website.
  4. The bot checks each heading to see if it matches the search term.
  5. Once a heading matches, the bot collects the content of each subsequent paragraph, heading or list until it reaches a heading that's the same level or higher.
  6. The bot processes the collected information to format lists and headings.
  7. Finally, the bot posts the results in the original Slack channel.

If the bot can't find anything, it'll notify the user so they don't have to wait for an answer that isn't coming.

How should we refer to the Chancellor? The bot has the answers

How should we refer to the Chancellor? The bot has the answers

If we're discussing a style question in Slack, the bot can provide the answer to everyone in the channel – hopefully making it easier to settle some debates.

Downsides of Slackbots

The bot should be useful when you want it, but stay out of the way when you don't. Nobody wants a bot which spams the chat with unnecessary messages or notifications.

It's also important to be aware of potential security risks. When you give a Slackbot access to a channel, you're allowing it to potentially access a lot of sensitive information – what everyone is saying, when users are online, or even when they are typing.

I created an entirely separate team just to test my bot in, so it hasn't made it to our actual chat yet. If we do unleash it upon our actual Slack team, we'll definitely need to do some more research into the security aspects first.

Go forth and build bots

While my Slackbot hasn't made it into production use yet, I'm still glad I built it. It was an interesting and fun little project which I hope has the potential to become really useful for our team.

If you use Slack, I'd recommend having a go at making your own bot. There are some powerful tools for building your own bots in your choice of languages – Node.js is especially popular.

If you've built a Slackbot, or have a favourite one that makes your working life much easier, let me know in the comments. I'm looking forward to seeing what everyone's come up with.

 

Work hard, bake hard

📥  Team

The Great British Bake Off is popular in our team, probably because our team is composed of humans. So, of course, we have enforced fun to go with it.

We call it the 'sweepbake' or 'sweepsbake' (opinions are divided on the extra s).

The rules are simple:

  • everyone in the office randomly draws a Bake Off contestant
  • when your contestant is eliminated, you must bring in baked goods, ideally homemade

The result is an onslaught of delicious carbohydrates that lasts for about three months.

Here are some of the treats we enjoyed this year:

Rhian's cheese straws

Rhian's cheese straws

Phil's cupcakes

Phil's cupcakes

Miao's cookies

Miao's cookies

Sean's apple pies

Sean's apple pies

Iris's lemon snickerdoodles

My lemon snickerdoodles

Fortunately, the campus has excellent gym facilities and some lovely running trails to balance all this out.

What I've learned in my first few weeks as a developer

📥  Development, Team

A little over two weeks ago, I started a new job in the Digital team as a Junior Developer.

While this job is new to me, the team isn't – I first joined in January 2014 as a Content Producer. But I'd been thinking about a possible move to development for a while, and found myself taking every opportunity to nose around our codebase and ask questions about how things worked. This escalated to building stuff in my free time (like a Rails app that makes it easier for our office to plan our massive orders for Schwartz Bros burgers). After a slightly scary interview, I was lucky to get the best of both worlds: moving my career in a new direction while staying with the team I've loved being part of for the last few years.

My new mission: build cool stuff that makes our users' lives easier. And while I've only just started, I've already learned a lot.

Turns out I am OK at this

Since this is my first job in development, I was a little nervous that it would take me a while to get up to speed and become a useful member of the team.

Fortunately, Phil and Tom apparently didn't share my nerves and had already drawn up a healthy to-do list for me to tackle. I was excited to be shipping code within my first week.

After getting through three relatively small stories, I moved on to my first bigger feature: making it possible for users to choose the order in which Team Profile list their members. As with all our team's work, this is now being reviewed by another developer and I'm looking forward to the feedback.

Content and development skills do overlap

The day-to-day of content and development might look pretty different. But our team shares a single set of Digital Principles, and those principles work for content, design and development alike.

Many of the things that were important when I was a Content Producer are still important as a Junior Developer, from working in an Agile way to taking the time to properly document processes and decisions. And striking the right balance of being clear and concise is valuable for writing both content and code.

Having experienced the challenges of content production and transition for myself, I also hope that will help me bring some unique insights to our development work.

Looking like a cool hacker

I've spent more time in the command line this fortnight than I probably have in my life. There's a lot to remember, but I'm already starting to see how it can speed up my workflow.

I've also started using the text editor Vim, which comes with Unix and is accessed through the command line. Vim looks arcane and terrifying. But it's actually not that difficult to get to grips with and has already saved me time.

Looking cool is still a perk.

Shipping useful things feels great

The first piece of work I shipped was a pretty small change to the list of all items in the Content Publisher. Previously, Person Profiles were just listed by the role holder name. I amended this to include the person's name as well.

This was a small tweak, but it solved a problem our users had been struggling with for a while – picking one Senior Lecturer out of a list of dozens is frustrating if you have to check each one individually.

Pushing to production to a round of applause felt really good. Knowing that it's something users have been looking forward to made it feel even better.

Development is fun

Okay, I already knew this from doing it in my free time. But it turns out it's fun professionally too. (Whew!)

Getting stuck on a problem can be frustrating, but the thrill of "it works!" when I finally hit the solution has yet to get old.

I'm also fortunate that everyone else is happy to answer questions, offer advice and help me out when I get stuck. Making things on my own was fun, but I prefer being part of the team. And I'm looking forward to continuing to learn.


Also, we're hiring right now – find out more about working in the Digital team.

 

Digital team sprint notes, 28 June – 11 July

📥  Sprint notes

If you are on campus, you can read about the latest Content Publisher changes as and when they happen at http://go.bath.ac.uk/beta-release-notes

What we've delivered

  • Allowed admins to set up labels in the Content Publisher
  • Finished some discovery work on how we can improve our styling for headings
  • Made caching more selective, so you no longer have to refresh certain pages to get the latest version (like the staff landing page or noticeboard)
  • Fixed several bugs for padding and spacing
  • Fixed a font size bug that was causing issues for landing pages in Safari
  • Continued working on our induction content for new students
  • Continued working on our next iteration of Worldwide
  • Published the first transitioned RIS pages

What we're going to deliver

  • Report on user research we did at the June Open Days
  • Redesign the header for smartphones so more content is initially visible
  • Allow admins to associate content items to labels
  • Implement collections in the Content Publisher
  • Implement lists of collections
  • Continue work on induction
  • Continue work on Worldwide