Have you ever merged a pull request for CSS fixes that appear harmless, only to discover that your application is broken somewhere else? Can you change globally applied styles with confidence that they have no side effects, without going through the whole application?
Manually going through every page after each small CSS change is a tedious task. Especially if you are completely sure that this tiny change won't break anything. Wouldn't it be great if there were a way to check through all documented use-cases, even before merging the pull requests with the styles, as part of the CI build? Well, of course there is.
The ideal workflow
The best time to prevent errors and improve the code is before merging it. There are a few lucky bits that align here:
- You keep web pages that act as a specification of where the styles will be used.
- PastShots generates screenshots of these pages.
- The screenshots are committed to the repository.
- When a pull request makes changes to the styles or spec pages, PastShots creates new screenshots of the pages and commits them as part of the pull request.
The beauty of the approach is that it packs quite a bit of benefits:
- There is reference markup along with the styles. Any changes to the markup are visible in the PR, along with reasoning why it changes.
- There are tests that show what has changed and how it looks.
- The test pages can be used during development.
- The Github interface for pull requests does a great job at highlighting the changes for a picture.
Example usage
The complete approach can be seen in the Kendo UI themes repository. Most of the PRs that introduce new styles also add a test page, or modify the preview of an existing one.
Here is a PR that changes the chat component styles. Notice how the shadows below the card are visible on the right, after the new styles are applied.
Pro tips
Since the inception of the idea, we've used this approach for a while. Here are some tips to make your development easier.
Keep test pages small
Leave most test pages small, just like you would keep unit tests small. This reduces the size of the output image, it doesn't bloat the repository, and it is easier to determine the locality of the change. When testing integration, consider replacing some of the nested content with empty containers, or removing it altogether.
Keep intermediate screenshots for code reviews
If a PR has multiple commits, keep the intermediate screenshots to facilitate easier code reviews. Having a screenshot of what has changed after a given commit is quite helpful for understanding. When you are ready to merge the PR, remove the intermediate screenshots with an interactive rebase and generate new ones. This keeps the updated images to a minimum, and prevents the git repo from bloating.
Epilogue: Reflection about CSS
CSS code is still code. The syntax may be different from C-like languages, but it can still be linted, tested and refactored. Preprocessor variables, or CSS custom properties, are subject to identical naming woes as variables in any other code. In terms of testing, CSS needs more visual tests, because CSS is visual in nature. This is what PastShots simplifies.