Vue: Create live screenshots from Vue components
Last modified Jan 24 2021 1:07 by Kees de Kooter
TL;DR
How can you make sure that the screenshots in your documentation reflect the actual components in your application? When the application is in flux - read: always - manually clicking through the app and taking screenshots by hand is not a feasible option. We can do better than that!
Render the actual components on a dedicated page in the application, populated with the proper demo data. And let the screenshots be taken by a headless browser!
Oh and this approach could also be applied the other front-end frameworks of course.
Screenshot page component
This vue component contains instances of all components to be screenshot. The components are "dumb views" that get their state through properties. That way the entire state can be set outside the component, and demo data can be prepared specifically for documentation purposes.
<section class="screenshot-container" data-name="<the target file name>">
<the-component :data="mockData"></the-component>
</section>
Route available only at dev time
Mount this view on a route only available at dev time.
if (process.env.NODE_ENV === 'development') {
routes.push({
path: '/screenshots',
components: {
default: Screenshots
}
})
}
Let puppeteer pull the shots
Puppeteer - the automated headless Chrome browser - will take care of making the screenshots. It loads your screenshot page and creates a screenshot of every screenshot-container
element.
The following nodejs script does the trick.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage();
await page.goto('<url-of-your-screenshot-page>')
// Get the handles for all screenshot elements
const elementHandles = await page.$$('.screenshot-container')
for (let elementHandle of elementHandles) {
// Get the file name from the `data-name` attribute
const fileName = await page.evaluate(
(element) => element.dataset.name,
elementHandle
)
const path = __dirname + '/out/' + fileName + '.png'
await elementHandle.screenshot({ path: path })
}
await browser.close()
})();