AngularでStoryshotsを動かす
Posted on January 29, 2020 at 21:00 (JST)
AngularでStoryshotsを動かすまでの方法をメモとして残す。
今回作成したコード: angular-storyshots-sample/mono-app
動作環境
OS: macOS Mojave ver. 10.14.6
Node: v12.14.0
@angular/cli: 9.0.0-rc.10
jest-preset-angular: 8.0.0
@storybook/angular: 5.3.9
StorybookとStoryshotsの概要
Storybook
UIコンポーネントを開発するのに便利なツール。
コンポーネントカタログ作成のため導入するケースも多い。
Storyshots
Jestのsnapshot testing
を、Storybookで作成したファイルをもとに行うためのアドオン。
※ レンダリング結果の画像比較を行うには別途puppeteer等と連動させる仕組みが必要。本記事では取り扱わない。
Angularプロジェクトへの導入
手順概要
- Angularプロジェクト作成
- Storybookを導入
- Jestを導入
- Storyshotsを導入
1. Angularプロジェクト作成
$ ng new sample --style=scss --strict
$ cd sample
2. Storybookを導入
下記コマンド実行により必要なライブラリのインストールと設定系/サンプルファイルの追加、およびpackage.jsonへstorybook実行用のscriptが追記が行われる。
$ npx -p @storybook/cli sb init --type angular
$ npm run storybook
でhttp://localhost:6006/
にコンポーネントカタログが表示できる。
3. Jestを導入
下記コマンドによりJestのインストール、およびKarma用設定ファイルの削除などが行われる。
$ npx ng add @briebug/jest-schematic
$ npm run test
を実行するとJestでテストが実行されることが確認できます。
4. Storyshotsを導入
4-1. storyshotsアドオンをインストール。
$ npm install --save-dev @storybook/addon-storyshots
4-2. src/storyshots.test.ts
ファイルを追加し、下記を記述。
import initStoryshots from '@storybook/addon-storyshots';
initStoryshots();
4-3. package.jsonへjest-preset-angularのファイルを正しく参照させるための設定を追記。
"jest": {
...
"moduleNameMapper": {
...
"jest-preset-angular/(.*)": "<rootDir>/node_modules/jest-preset-angular/build/$1"
},
....
$ npm test
でテストを実行すると通常のテストの後にStoryshotsが動き、src/__snapshots__/storyshots.test.ts.snap
が生成される。
適用例
Bulma(CSS framework)を利用したComponentを作成し、Storyshotsを利用する。
まず、bulmaをインストール
$ npm install --save bulma
angular.json
にnode_modulesディレクトリ下からcssを読み込む設定を追記(2箇所)
"styles": [
"src/styles.scss",
"node_modules/bulma/css/bulma.css"
],
Notificationコンポーネントをcliで追加
$ ng g component elements/notification
notification.component.ts
を下記に書き換え
import {Component, EventEmitter, OnInit, Output} from '@angular/core';
@Component({
selector: 'app-notification',
templateUrl: './notification.component.html',
styleUrls: ['./notification.component.scss']
})
export class NotificationComponent {
@Output() closed = new EventEmitter();
constructor() { }
close() {
this.closed.emit();
}
}
notification.component.html
を下記に書き換え
<div class="notification is-primary">
<button class="delete" (click)="close()"></button>
<ng-content></ng-content>
</div>
notification.component.spec.ts
をnotification.component.stories.ts
にリネームし、下記に書き換え
import {action} from '@storybook/addon-actions';
import {NotificationComponent} from './notification.component';
import {storiesOf} from '@storybook/angular';
storiesOf('Notification', module)
.add('content', () => ({
moduleMetadata: {
declarations: [NotificationComponent],
},
template: `<app-notification>Hello world!</app-notification>`,
}))
.add('event', () => ({
component: NotificationComponent,
props: {
closed: action('Clicked!'),
},
}));
$ npm run storybook
でカタログを立ち上げ確認。
$ npm run test
でstoryshotsが動いていることを確認。
notification.component.html
を少し変更し、再度テストを実行すると下記のように差分が表示される。
FAIL src/storyshots.test.ts (6.097s)
● Storyshots › Notification › content
expect(received).toMatchSnapshot()
Snapshot name: `Storyshots Notification content 1`
- Snapshot - 1
+ Received + 1
@@ -4,11 +4,11 @@
target={[Function ViewContainerRef_]}
>
<ng-component>
<app-notification>
<div
- class="notification is-primary"
+ class="notification"
>
<button
class="delete"
/>
Hello world!
遭遇したエラー
package.jsonへsetupJestを見つけるための設定(手順:4-3)を追加しないと、下記エラーが発生する。
$ npm test
PASS src/app/app.component.spec.ts
FAIL src/storyshots.test.ts
● Test suite failed to run
Cannot find module 'jest-preset-angular/setupJest' from 'loader.js'
以上。
参考URL
- Storybook for Angular
- storybookjs/storybook
- Issues with @storybook/addon-storyshots #8853
- Angular で Storybook を使うための手順まとめ
- buluma