thingsinjars

  • 28 Nov 2011

    cssert – Like ‘assert’ but with CSS at the front

    This continues on from my post about CSS verification testing

    cssert – pronounced however you feel like it – is my attempt at bringing some kind of style verification into an automated build process. If you've read the previous article, you'll know that this falls into the second group of CSS test frameworks, style measurement and comparison. The system works exactly as I described above – your test files have a basic HTML structure created by traversing the DOM from the element being tested upwards. You could also include your entire HTML in the test file if you liked, it would just be unnecessary in most cases.

    I've created a couple of (for me, at least) helpful utilities which allow these test cases to be generated from a page via a bookmarklet and then run in the browser or on the command-line. Running the tests in the browser is useful for quick human verification while the command-line interface can be integrated into an automated build system if you like that kind of thing. The test file structure is quite simple (all samples here taken from the Twitter Bootstrap project:

    First, we have the test file opening structure:

    <!doctype html><html><head><title>cssert test page</title><link rel="stylesheet" href="../lib/cssert.css"></head><body><h1>cssert Test cases</h1><p>click to expand test</p><script type="text/html">/*==

    Then we have the name of the test:

    Intro Paragraph

    Then we have the skeleton DOM:

    <!doctype html><html><head><meta charset="utf-8"><base href="http://twitter.github.com/bootstrap/examples/hero.html"><link href="../1.3.0/bootstrap.css" rel="stylesheet"><style type="text/css">
          body {
            padding-top: 60px;
          }
        </style><style>#cssert-style-modal {display:none;position: fixed;top: 10%;left: 50%;margin-left: -350px;width: 700px;background: #39c;color: white;padding: 10px;color: #fff;text-shadow: 0 1px 0 rgba(0,0,0,.3);background-image: -webkit-linear-gradient(-45deg, rgba(255,255,255,0), rgba(255,255,255,.1) 60%, rgba(255,255,255,0) 60%);border-radius: 5px;border: 1px solid #17a;box-shadow: inset 0 0 0 1px rgba(255,255,255,.3);}#cssert-style-modal ul,#cssert-style-modal li {margin:0;padding:0;font-size:11px;list-style:none;}#cssert-style-modal>ul>li {float:left;width:140px;font-size:13px;}#cssert-style-modal ul {margin-bottom:10px;}#cssert-pre {position:fixed;top:10px;right:10px;background:white;border:1px solid gray;width:200px;height:200px;overflow:auto;}#cssert-drag {position:fixed;top:210px;right:10px;background:white;border:1px solid gray;width:200px;height:20px;overflow:auto;}</style></head><body><div class="container"><div class="hero-unit"><p>Vestibulum id ligula porta felis euismod semper. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p></div></div></body></html>

    The CSS selector identifying the element to verify:

    html body div div p

    And the styles we wish to verify:

    {"font-family":"'Helvetica Neue', Helvetica, Arial, sans-serif","font-weight":"200","font-style":"normal","color":"rgb(64, 64, 64)","text-transform":"none","text-decoration":"none","letter-spacing":"normal","word-spacing":"0px","line-height":"27px","text-align":"-webkit-auto","vertical-align":"baseline","direction":"ltr"}

    A test file can contain as many test units as you like. At the very end is the close of the test file structure

    */</script><script src="../lib/cssert.js"></script></body></html>

    You'll probably notice the crucial bit in the test structure is the base element. The CSS available from the location specified here is the thing we are actually testing. In typical test lingo, the structure we have in our test file is the mock and our tests work by asserting the values ‘output’ from applying the CSS to this structure are as expected.

    Running the tests

    Running the tests in-browser

    Open the test page in a browser. That's it. If it's green and says 'passed', the test passed. If it's red and says 'failed', the test failed. You can see the output by clicking on the title of the test.

    This works by loading the test file, creating an iframe and injecting the test case into the iframe as source. It then looks into the iframe and measures the styles. If they match those specified in the test file, it passes, otherwise, it fails. Clicking on the test title simply removes the position:absolute which is hiding the iframe.

    Running the tests on command-line

    The exact same test page can also be used with the command-line interface. cssert uses PhantomJS to run the tests in a headless webkit instance. You'll need to install PhantomJS into your path after downloading it. Place your test case in the tests folder and run:

    $ ./cssert testcase.html

    To run all tests in the tests folder at once, simply run with no arguments:

    $ ./cssert

    This works by, again, loading the HTML from the test files. In this case, the structure is injected into a new headless browser window. The styles are measured and the output is redirected to stdout. Each browser window test is also rendered as a PNG so you can see what failed if any did.

    Limitations

    I'm not saying this is the ultimate solution to CSS testing. Declarative languages don't sit well with testing. This is as close as I can get for the moment. I'm also not going to be able to head off or counter all possible complaints or criticisms but I will cover a couple.

    Firstly, most of the limitations you'll run into are caused by using the automatically generated tests. They're good for creating a starting point but at the moment, they need to be tweaked for many cases.

    Sibling selectors

    Because the test generates the DOM via following parents up the structure, sibling elements are ignored. These styles are still testable, though. Simply add the sibling element into your HTML test block.

    Styles modified by JS

    The styles are measured on the element as it is when the case is generated. The test compares this against the styles provided by the CSS. If the element contains JS-only styles not added by CSS, they will not be correctly matched. Modify your test case to allow for this.

    Why not use Selenium?

    This, essentially does the same as Selenium would do if you took the time to set up your test cases. This makes it much easier to set up test cases, though.

    @font-face!

    If your @font-face declaration contains a suggested 'local' source (as recommended in Paul Irish's bulletproof syntax), a bug in QTWebkit will prevent the test case from running correctly.

    Installation

    Just clone the git project from git@github.com:thingsinjars/cssert.git and you're good to go.

    The tests directory comes with some sample tests generated using Twitter's Bootstrap project. Put your tests in that same place.

    CSS, Development, Geek

  • 31 Oct 2011

    Copy-paste coding

    This weekend, I had a spare couple of hours on Saturday night (as often happens when you have a kid) so I decided to pass the time with a bit of copy-paste coding.

    I grabbed a bit of example code for a top-down racing game built using Box2d and GameJs. I then grabbed a Google Maps demo and a Nokia Maps demo and smooshed them together. I've seen a few racing games before so I know there's nothing innovative here, it's just a bit of silliness.

    The results

    • Driving on Nokia Maps
    • Driving on Google Maps

    Copy-Paste: Not a bad thing

    There are many developers who will tell you that blindly copy-pasting is a terrible way to code. They make the valid points that you don't understand something if you don't read it properly and that you'll end up stuck down an algorithmic cul-de-sac with no way to three-point-turn your way out (although they may phrase it differently). These are valid points but...

    If I'd sat down on Saturday night and thought "I want to build something in Box2D" then gone to the site, downloaded the library, read the docs and loaded the examples, by the time I had understood what I was doing, Sunday morning would have come round and I'd still have GameJS to read up on. There's absolutely no harm in blindly catapulting yourself a long way down the development track then looking round to see where you are. Sure, you'll end up somewhere unfamiliar and you may end up with absolutely no clue what the code around you does but at least you have something to look at while you figure it out. At least a few times, you'll find something almost works and a quick search of the docs later, you've figured it out and know what it's doing.

    Basically, copy-pasting together a simple little demo and making it work is a lot more interesting than taking baby-steps through example code and beginner tutorials. Don't be too careful about trying to build something complicated.

    An Idea

    If you're in the mood for copy-paste coding, try taking the two demos above (Google and Nokia), grab the node.js server from the multi-user page experiment and figure out how to have multiple racers on the same map (by transmitting angle and geo-coords).

    Development, Development, Toys, Guides

  • 31 Oct 2011

    Copy-paste coding

    This weekend, I had a spare couple of hours on Saturday night (as often happens when you have a kid) so I decided to pass the time with a bit of copy-paste coding.

    I grabbed a bit of example code for a top-down racing game built using Box2d and GameJs. I then grabbed a Google Maps demo and a Nokia Maps demo and smooshed them together. I've seen a few racing games before so I know there's nothing innovative here, it's just a bit of silliness.

    The results

    • Driving on Nokia Maps
    • Driving on Google Maps

    Copy-Paste: Not a bad thing

    There are many developers who will tell you that blindly copy-pasting is a terrible way to code. They make the valid points that you don't understand something if you don't read it properly and that you'll end up stuck down an algorithmic cul-de-sac with no way to three-point-turn your way out (although they may phrase it differently). These are valid points but...

    If I'd sat down on Saturday night and thought "I want to build something in Box2D" then gone to the site, downloaded the library, read the docs and loaded the examples, by the time I had understood what I was doing, Sunday morning would have come round and I'd still have GameJS to read up on. There's absolutely no harm in blindly catapulting yourself a long way down the development track then looking round to see where you are. Sure, you'll end up somewhere unfamiliar and you may end up with absolutely no clue what the code around you does but at least you have something to look at while you figure it out. At least a few times, you'll find something almost works and a quick search of the docs later, you've figured it out and know what it's doing.

    Basically, copy-pasting together a simple little demo and making it work is a lot more interesting than taking baby-steps through example code and beginner tutorials. Don't be too careful about trying to build something complicated.

    An Idea

    If you're in the mood for copy-paste coding, try taking the two demos above (Google and Nokia), grab the node.js server from the multi-user page experiment and figure out how to have multiple racers on the same map (by transmitting angle and geo-coords).

    Development, Development, Toys, Guides

  • 28 Oct 2011

    Workflow. The flow. Of work.

    How to actually work

    Don’t tell anyone (particularly not your clients and especially not my clients) but making websites is really very easy. Don't make it harder by deliberately hindering yourself. You should always try to travel the shortest distance between “amends needs done” and “amend is done”. Again, I hear a “Pah!” in the distance, “Well, that’s obvious.”, but is it? Are you sure you’re ‘Being all you can be’?

    The shortest distance

    Okay, picture the scene: you've run out of socks. You need to put on a load of washing. The washing is in a pile in the corner of the room. You hunch over, pick up all the socks, pants, t-shirts and walk, waddle and totter to the washing machine. As you walk, you drop a sock and bend down to pick it up, dropping another. You recover that one and another falls. Eventually, you make it to the washing machine after a few minutes, put everything in, throw in some powder and set it going. As you head back to your bedroom, you spot three more socks that you missed. Darn.

    Okay, picture the scene: you've run out of socks. You need to put on a load of washing. Fortunately, every time you took your socks off, you put them straight in the washing machine. You wander to the kitchen, put in the powder and switch it on. Done.

    Any time you try to do anything, the more steps involved between intention and completion, the more likely it is to go wrong. Whether the intention is 'wear clean socks' or 'update this website', if you can do it in a handful of steps, you'll make fewer mistakes than if you have to do it in a hunched-over armful.

    Workflow. The flow. Of Work.

    The next time you're making an amend somewhere, watch yourself. Watch which applications you jump between. Don't just make your changes, pay attention to how you do them. Are you jumping between text editor and FTP client? Text editor and web browser? FTP and Subversion? Just take a few minutes to think about which steps you might be able to miss out. For instance, if you use Textmate and Transmit, you can set up DockSend so that pressing ctrl-shift-f then 2 will upload the file you currently have open to the same place on the server. You can now change the editor↔FTP↔browser cycle to editor↔browser.

    However...

    Seamless does not imply flawless. Don't be tempted to simplify to the stage where you don't need any interaction between making a change and the change being live. If you rely on the fact that your changes 'just happen', you might be tempted not to check. That's the point at which they don't 'just happen'.

    This article is modified from a chapter in a book Andrew and I were writing a couple of years ago about web development practical advice. Seeing as we both got too busy to finish it, I'm publishing bits here and there. If you'd like to see these in book form, let me know.

    Geek, Development, Guides

  • newer posts
  • older posts

Categories

Toys, Guides, Opinion, Geek, Non-geek, Development, Design, CSS, JS, Open-source Ideas, Cartoons, Photos

Shop

Colourful clothes for colourful kids

I'm currently reading

Projects

  • Awsm Street – Kid's clothing
  • Stickture
  • Explanating
  • Open Source Snacks
  • My life in sans-serif
  • My life in monospace
Simon Madine (thingsinjars)

@thingsinjars.com

Hi, I’m Simon Madine and I make music, write books and code.

I’m the Engineering Lead for komment.

© 2025 Simon Madine