At this time of the year it’s when we, at NodeConf Argentina, start to announce new speakers. There are a few checks we usually run for the website after the HTML changes have been made. Those are:

  • the changes don’t break anything
  • Twitter social card looks fine
  • Facebook social card looks fine

I was growing tired of manually checking those last two for every change and thought “there must be a way to automate these checks, right?” Well turns out for Twitter I found a Card Validator website and Facebook’s have their URL Debugger. This is how I managed to use Puppeteer to browse Twitter’s Card Validator, take a screenshot, upload it to Imgur and paste it as comment on a pull request.

First things first

I already had in place the configuration for TravisCI to run a build and deploy for every PR. If you want to know details on how I configured it you can read more on Running Lighthouse for every PR with Travis CI. I was using Surge.sh to run deployments, but with Surge.sh’s subdomains a specific robots.txt will be overwritten and it won’t work for the card validator.

I switched to now, using public deployments turned out to be very straightforward.

Enter the puppeteer world

I had Lighthouse running against the now deployment and there were three things missing:

  1. get the list of modified files
  2. use puppetteer to make a screenshot
  3. upload the screenshot to a service

For the first step I used a git command that, if a source branch is not specified, it will get the diff files from target branch to your current branch (the one for the pull request). This is the command:

1
$ git diff --name-status master

For Puppeteer to take the screenshot I needed to impersonate my Twitter session, followed by entering the URL I wanted to check and the last thing would be clicking the “Preview Card” button. To impersonate a Twitter session I leveraged the page.setCookie method and passed the cookie through an environment variable. Next I emulated a viewport that would work well for me, then navigated to the Card Validator page

1
2
3
await page.goto('https://cards-dev.twitter.com/validator', {
waitLoad: true
});

and used the output of step 1 with the deployment URL from now altogether (passed as argument)

1
2
await page.click(textInputSelector);
await page.keyboard.type(process.argv[2]);

For the screenshot to display correctly I needed to wait for an iframe on the page to load. But it’s far from perfect because I couldn’t find a consistent solution without additionally waiting for an arbitrary amount of milliseconds. The whole file is under 70 lines of code, you can check it out here.

To complete step n° 3 I used Imgur and a handy bash script I found. You can specify your client ID by adding the IMGUR_CLIENT_ID environment variable to your CI builds.

How the end result looks like on a pull request.

Closing thoughts

It would be useful to have the social card check for Facebook too, but they upload images asynchronously making the crawling by Puppeteer more tedious.
At this point I will say that Puppeteer is a very powerful tool, but I also think there a few bits to be improved like the API for asynchronous events. Even after waiting for different events fired on a dynamically-inserted iframe, I had to add an arbitrary timer for the changes to be rendered.
And by the way, you shouldn’t really impersonate your Twitter session for anything serious. Just create a user for your automation.

Have you used Puppeteer in your CI flow? Let me know in the comments!