Skip to content

Commit

Permalink
feat: basic screenshot plugin, related #34
Browse files Browse the repository at this point in the history
  • Loading branch information
Akryum committed May 1, 2022
1 parent ee4c399 commit aed2219
Show file tree
Hide file tree
Showing 18 changed files with 731 additions and 84 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions examples/vue3-screenshot/histoire.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from 'histoire'
import { HstScreenshot } from '@histoire/plugin-screenshot'

export default defineConfig({
plugins: [
HstScreenshot({
ignored: ({ file }) => file.includes('tailwind-tokens'),
}),
],
})
19 changes: 19 additions & 0 deletions examples/vue3-screenshot/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "histoire-example-vue3-screenshot",
"version": "0.0.1",
"private": true,
"scripts": {
"story:dev": "histoire dev",
"story:build": "histoire build",
"story:preview": "histoire preview"
},
"dependencies": {
"vue": "^3.2.31"
},
"devDependencies": {
"@histoire/plugin-screenshot": "workspace:*",
"@vitejs/plugin-vue": "^2.3.1",
"histoire": "workspace:*",
"vite": "^2.9.1"
}
}
3 changes: 3 additions & 0 deletions examples/vue3-screenshot/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
plugins: [],
}
11 changes: 11 additions & 0 deletions examples/vue3-screenshot/src/components/InjectDemo.story.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts" setup>
import InjectDemo from './InjectDemo.vue'
</script>

<template>
<Story title="Story setup">
<Variant>
<InjectDemo />
</Variant>
</Story>
</template>
12 changes: 12 additions & 0 deletions examples/vue3-screenshot/src/components/InjectDemo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script lang="ts" setup>
import { inject } from 'vue'
console.log('injecting demo')
const demo = inject('demo')
</script>

<template>
<div class="demo">
{{ demo }}
</div>
</template>
12 changes: 12 additions & 0 deletions examples/vue3-screenshot/src/histoire.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.demo {
color: #10B981;
}

html.htw-dark {
background: #27272a ;
color: #e9e9ed;
}

.__histoire-sandbox input {
border: solid 1px #ccc;
}
6 changes: 6 additions & 0 deletions examples/vue3-screenshot/src/histoire.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import './histoire.css'
import { defineSetupVue3 } from 'histoire/client'

export const setupVue3 = defineSetupVue3(({ app }) => {
app.provide('demo', 42)
})
22 changes: 22 additions & 0 deletions examples/vue3-screenshot/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/// <reference types="histoire" />

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// @TODO investigate ESM errors when this is imported in vite.config.ts
// https:/vitejs/vite/issues/7981
// import { HstScreenshot } from '@histoire/plugin-screenshot'

export default defineConfig({
plugins: [
vue(),
],

histoire: {
// plugins: [
// HstScreenshot(),
// ],

// Alternative way of specifying histoire config
setupFile: '/src/histoire.setup.ts',
},
})
20 changes: 20 additions & 0 deletions packages/histoire-plugin-screenshot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Histoire Screenshot visual regression testing

```
pnpm add -D @histoire/plugin-screenshot
```

Add the plugin in histoire config:

```js
import { defineConfig } from 'histoire'
import { HstScreenshot } from '@histoire/plugin-screenshot'

export default defineConfig({
plugins: [
HstScreenshot({
// Options here
}),
],
})
```
42 changes: 42 additions & 0 deletions packages/histoire-plugin-screenshot/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "@histoire/plugin-screenshot",
"version": "0.2.5",
"description": "Histoire plugin to take screenshots for visual regression testing",
"license": "MIT",
"author": {
"name": "Guillaume Chau"
},
"repository": {
"url": "https:/Akryum/histoire.git",
"type": "git",
"directory": "packages/histoire-plugin-screenshot"
},
"publishConfig": {
"access": "public"
},
"type": "module",
"exports": {
".": "./dist/index.js",
"./*": "./*"
},
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"build": "rimraf dist && tsc -d",
"watch": "tsc -d -w --sourceMap"
},
"dependencies": {
"capture-website": "^2.3.0",
"defu": "^6.0.0",
"fs-extra": "^10.1.0",
"pathe": "^0.2.0"
},
"devDependencies": {
"histoire": "workspace:*",
"typescript": "^4.6.3"
},
"peerDependencies": {
"histoire": "^0.2.5"
}
}
77 changes: 77 additions & 0 deletions packages/histoire-plugin-screenshot/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import path from 'pathe'
import fs from 'fs-extra'
import type { Plugin } from 'histoire'
import { defu } from 'defu'

interface ScreenshotPresets {
/**
* Screenshot width.
*/
width?: number
/**
* Screenshot height.
*/
height?: number
}

export interface ScreenshotPluginOptions {
/**
* Folder were screenshots will be saved.
*/
saveFolder?: string
/**
* Ignored stories.
*/
ignored?: (payload: { file: string, story: { title: string }, variant: { id: string, title: string } }) => boolean
/**
* Presets for each screenshot.
*/
presets?: ScreenshotPresets[]
}

const defaultOptions: ScreenshotPluginOptions = {
saveFolder: '.histoire/screenshots',
presets: [],
}

export function HstScreenshot (options: ScreenshotPluginOptions = {}): Plugin {
const finalOptions: ScreenshotPluginOptions = defu(options, defaultOptions)
if (!finalOptions.presets.length) {
finalOptions.presets.push({
width: 1280,
height: 800,
})
}
return {
name: '@histoire/plugin-screenshot',

onBuild: async api => {
const { default: captureWebsite } = await import('capture-website')
await fs.ensureDir(finalOptions.saveFolder)

api.onRenderStory(async ({ file, story, variant, url }) => {
if (finalOptions.ignored?.({
file,
story: {
title: story.title,
},
variant: {
id: variant.id,
title: variant.title,
},
})) {
return
}
console.log('Rendering screenshot for', file, 'title:', story.title, 'variant:', variant.id, 'title:', variant.title)
for (const preset of finalOptions.presets) {
await captureWebsite.file(url, path.join(finalOptions.saveFolder, `${story.id}-${variant.id}.png`), {
overwrite: true,
width: preset.width,
height: preset.height,
fullPage: true,
})
}
})
},
}
}
42 changes: 42 additions & 0 deletions packages/histoire-plugin-screenshot/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "node",
"outDir": "dist",
"rootDir": "src",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"removeComments": false,
"resolveJsonModule": true,
"skipLibCheck": true,
"types": [
"node",
"@peeky/test"
],
"lib": [
"ESNext",
"DOM"
],
"sourceMap": false,
"preserveWatchOutput": true,
"preserveSymlinks": true,
// Strict
"noImplicitAny": false,
"noImplicitThis": true,
"alwaysStrict": true,
"strictBindCallApply": true,
"strictFunctionTypes": true,
// Volar
"jsx": "preserve",
},
"include": [
"src"
],
"exclude": [
"node_modules",
"generated/**/*",
"dist/**/*",
"src/**/*.spec.ts"
]
}
Loading

0 comments on commit aed2219

Please sign in to comment.