1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

nuxt/storybook+storybook/addon-interactions導入でやったこと

Last updated at Posted at 2022-05-24

Nuxtjs-v2.15.8 nuxt/storybook-v4.3.1 storybook/addon-interactions-v6.4.22

はじめに

nuxtjs/storybook+storybook/addon-interactionsの導入で少しハマったので記事にしました。
大した内容ではないですが、あまり同じ構成の情報が見つからなかったためいつか誰かのためになれば幸いです。
導入に当たっては下記の記事を大変参考にさせていただきました。下記の記事で触れていない内容について記載します。
https://zenn.dev/azukiazusa/articles/storybook-interaction-testing

やったこと

バージョンを揃える

nuxt/storybook4.3.1ではアドオンのバージョンは6.4.22になっています。
storybook/addon-interactionsをインストールする時はバージョン指定することになります。

npm install -D storybook/addon-interactions@6.4.22

下記のライブラリに関しては、対応時の最新版で動作しています。
@storybook/jest: 0.0.10
@storybook/test-runner: 0.0.8
@storybook/testing-library: 0.0.11

ステップ実行を有効にする

ステップを有効にするためにはStorybookのmain.jsに下記を設定する必要があります。

module.exports = {
  features: {
    interactionsDebugger: true,
  },
};

nuxt/storybookではこれをnuxt.config.tsで指定することが出来なかったため、ejectでStorybookの設定ファイルを外出しする必要があります。

npx nuxt storybook eject

.storybookフォルダが生成されるので、その中のmain.jsにfeaturesおよびinteractionsDebuggerを設定してください。

withinではなくscreenを使う

こちらは環境要因もあるかもしれませんが、NuxtのユニバーサルモードではStorybook上でF5リロードするとcanvasから要素を取得することが出来ませんでした。

Sample.stories.ts
import { within } from '@storybook/testing-library'
...
Default.play = async ({ canvasElement }) = {
  const canvas = within(canvasElement)
  const textbox = await canvas.findByRole('textbox')
}

上記では下記のエラーでテストが失敗してしまいました。

Unable to find role="textbox"

Ignored nodes: comments, <script />, <style />
<div
  id="root"
/>

Ignored nodes: comments, <script />, <style />
<div
  id="root"
/>

下記のようにwithinではなくscreenから要素を取得することで解決しました。

Sample.stories.ts
import { screen } from '@storybook/testing-library'
...
Default.play = async () = {
  const textbox = await screen.findByRole('textbox')
}

ただし、READMEにはWhile you can technically use screen, it's recommended to use within(canvasElement). Besides giving you a better error message when a DOM element can't be found, it will also ensure your play function is compatible with Storybook Docs.とあるのでなるべくwithinで対応出来るように注視していきたいと思います。

アイコンボタンを取得する

今回のプロジェクトではUIフレームワークにVuetifyを使っており、マテリアルアイコンのみを使ったボタンもあります。
そういったボタンはtext等で要素の取得が出来ないため、aria-labelを適用することで見つけられるようになります。

CloseButton.vue
<template>
  <v-btn icon aria-label="close">
    <v-icon size="18px">mdi-close</v-icon>
  </v-btn>
</template>
...
Sample.stories.ts
...
Default.play = async () = {
  const closeButton = await screen.findByRole('button', { hidden: true, name: /close/i })
  ...
}

おわりに

Nuxt3も控えているのでもっと安定するかと思いますが、現状でもこれだけの対応でStorybookを活用してテストを書いていくことが出来ます。
より良い方法等あれば教えていただけると嬉しいです。
また何かあれば追記していきたいと思います。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?