Easily Check the Mobile-Friendliness of your Site with pageres

5 years ago

I always make an effort to ensure my clients are up to date on what I am doing at a given time, but often pictures do speak much larger than words. One thing I've found very helpful and instituted on many projects is regular sharing screenshots of my progress. Because I am a big advocate of responsive design, I try to include screenshots at several resolutions. This helps keeps everyone up to date, but also assists you, QA, and the client find visual issues early on.

Manually creating screenshots, especially at different resolutions can be very tedious. Fortunately, there are some great tools out their to help assist in this process. pageres is one of those and because it is easily customizable, you can easily tweak it to your needs.

This project uses pageres in conjunction with some basic configuration options and a site map. Based on that, it will create a time-stamped base directory, then subfolders for each individual page. Based on the resolutions you provide, images will then be created using pageres. Finally an static html file will be created for viewing and sharing.

Note: It should go without saying that this is only complimentary to what QA does. It is great for the high-level tests, but not for depth and breadth tests like those for UX or cross-browser testing.


Instructions

npm start
npm run screenshots

Sharing Instructions

  • Zip the target directory and send or share
  • Unzip and open index.html file to view

Note: If you have a ton of screenshots or sending to a large audience, and don't want to risk the wrath of your Exchange admin, I'd recommend copying to a network drive or hosting on a static server. 😀


Integrate in your own Project

npm install rimraf pageres --save-dev
  • copy the screenshots directory
  • update screenshots\config.js
    • baseUrl - base url of your site. Just make sure it is running.
    • siteTitle - will populate title tag in the HTML file
    • targetDirectory - used for output directory (default is based on date YYYY-MM-DD)
    • resolutions - array of resolutions
  • update screenshots\siteMap.js (If you have a different format, just tweak the loopSiteMap function in build.js)
  • ensure your site is up and running
  • add the following to your package.json
"scripts": {
  "screenshots": "node ./screenshots/build.js"
}
npm run screenshots

Screenshot

  • Open HTML file to view screenshots
  • Click on title to navigate to page
  • Click on images to see them individually

screenshot


Code

const Pageres = require('pageres')
const rimraf = require('rimraf')
const fs = require('fs')

const config = require('./config')
const siteMap = require('./siteMap')

const baseDirectory = `${__dirname}/output`
const targetDirectory = `${baseDirectory}/${config.targetDirectory}`
const templateName = `${__dirname}/template.html`
const templateTarget = `${targetDirectory}/index.html`
let html = ''
const totalWidth = config.resolutions.reduce((total, item) => {
  return (total = parseFloat(total) + parseFloat(item.split('x')[0]))
})

const percentages = config.resolutions.map(item => {
  const percent = item.split('x')[0] / totalWidth
  return parseFloat(percent) * (100 - config.resolutions.length).toFixed(2)
})

const rebuildDirectory = cb => {
  if (!fs.existsSync(baseDirectory)) {
    fs.mkdirSync(baseDirectory)
  }
  rimraf(targetDirectory, () => {
    fs.mkdirSync(targetDirectory)
    cb()
  })
}

const buildHtmlFile = () => {
  fs.createReadStream(templateName).pipe(fs.createWriteStream(templateTarget))
  fs.readFile(templateTarget, 'utf8', function(err, text) {
    if (err) {
      console.log(err)
    } else {
      text = text.replace('SCREENSHOTS_HTML', html)
      text = text.replace('SCREENSHOTS_TITLE', config.siteTitle + ' - Screenshots')
      fs.writeFile(templateTarget, text, function(err) {
        if (err) {
          console.log(err)
        }
      })
    }
  })
}

const updateHtml = (slug, title) => {
  html += `<div>`
  html += `<h1>
              <a target="_blank" href="${config.baseUrl}${slug}">
                ${title} - ${config.baseUrl}${slug}
              </a>
            </h1>`
  html += config.resolutions
    .map(
      (resolution, index) =>
        `<div class="img-container" style="width:${percentages[index]}%">
      <h3>${resolution}</h3>
      <a target="_blank" href="./${title}/${resolution}.png">
        <img src="./${title}/${resolution}.png" />
      </a>
    </div>`
    )
    .join('')
  html += '</div>'
}

const createScreenshot = (slug, title) => {
  console.log(title + ' - creating screenshot...')
  const dest = `${targetDirectory}/${title}`
  new Pageres({ delay: 2 })
    .src(config.baseUrl + slug, config.resolutions, { filename: '<%= size %>' })
    .dest(dest)
    .run()
    .then(() => console.log(title + ' - done'))
}

const loopSiteMap = pages => {
  pages.forEach(page => {
    createScreenshot(page.url, page.title)
    updateHtml(page.url, page.title)
    if (page.children) {
      loopSiteMap(page.children)
    }
  })
}

rebuildDirectory(() => {
  loopSiteMap(siteMap)
  buildHtmlFile()
  console.log('HTML File Available Here:')
  console.log(templateTarget)
})
Source Code

References

pageres

Discuss on Twitter