一個使用 `@storybook/test-runner` 提供穩定螢幕截圖功能的工具。

在 Github 上檢視

storycap-testrun 具有類似於 storycap 內部的 Stories 穩定性檢查功能,可以準確截取 Stories 的螢幕截圖 :camera

為什麼選擇 storycap-testrun?

當使用 @storybook/test-runner 進行視覺迴歸測試時,waitForPageReady 用於在截取螢幕截圖前等待。這僅支援最少的穩定性檢查。因此,在實際使用案例中,有必要設計方法進行更準確的穩定性檢查。

storycap 透過使用 CDP 監控 Stories 在瀏覽器中渲染時的各種指標來實現穩定的拍攝。storycap-testrun 遵循 storycap 的策略,執行準確檢查渲染內容穩定性的螢幕截圖擷取。此外,它還提供一種機制,透過驗證多個擷取的螢幕截圖影像的雜湊值是否相同,來檢查渲染內容的穩定性。

此外,它還提供啟發式工具來避免不穩定的測試,例如遮罩和移除,可以在每個 Story 的參數中指定。

功能

  • 渲染內容的高穩定性檢查
  • 準確等待 Play Function
  • 使用 Hook 在螢幕截圖擷取前後進行自訂
  • 不穩定元素的遮罩
  • 不穩定元素的移除
  • 不穩定元素的跳過

限制

  • 無法擷取多個視窗
  • 不支援像 :hover:focus、點擊等變體。
    • 雖然這是 storycap 支援的便利功能,但不支援,以避免影響在 postVisit 中執行的其他進程。

需求

安裝

透過 npm 安裝

$ npm install --save-dev storycap-testrun

開始使用

請事先設定 @storybook/test-runner

您可以透過在 postVisit 中呼叫 screenshot 函式立即開始使用。

// .storybook/tesr-runner.ts
import type { TestRunnerConfig } from '@storybook/test-runner';
import { screenshot } from 'storycap-testrun';

const config: TestRunnerConfig = {
  async postVisit(page, context) {
    await screenshot(page, context, {
      /* options */
    });
  },
};

export default config;

[!IMPORTANT] 由於 screenshot 函式會在內部自動執行穩定性檢查,因此不需要像 waitForPageReady 這樣的等待函式。

$ test-storybook

然後,只需適當地執行 @storybook/test-runner 即可。

預設情況下,螢幕截圖影像會儲存在 __screenshots__ 目錄中。

TypeScript 設定

透過匯入 ScreenshotParameters 並合併您所使用框架的類型,您可以為每個 Story 中指定的參數啟用類型檢查。

import type { ScreenshotParameters } from 'storycap-testrun';

// Replace it with the framework you are using.
declare module '@storybook/react' {
  interface Parameters {
    screenshot?: ScreenshotParameters;
  }
}

API

screenshot(page, context, options)

  • page: Page
    • postVisit 中傳遞的 Playwright 頁面實例。
  • context: TestContext
  • options: ScreenshotOptions
  • 返回:Promise<Buffer | null>
    • 擷取的螢幕截圖影像的緩衝區。如果指定了 skip: true,則返回 null

選項

可以指定為 screenshot 函式第三個參數的選項。

output.dry

類型: boolean
預設: false

如果指定 true,則 screenshot 函式在執行時不會儲存影像。當處理返回的緩衝區時,這很有用。

output.dir

類型: string
預設: path.join(process.cwd(), '__screenshots__')

指定儲存螢幕截圖影像的根目錄。

output.file

類型: string | ((context: TestContext) => string)
預設: path.join('[title]', '[name].png')

指定每個 Story 的螢幕截圖影像的檔案名稱。

當指定 string 時,可以使用以下範本

  • [id]:Story ID
  • [title]:Story 的標題
  • [name]:Story 的名稱

flakiness.metrics.enabled

類型: boolean
預設: true

指定 true 時,它會監控與 Story 渲染相關的幾個指標並執行穩定性檢查。

[!WARNING]
由於此進程依賴 CDP,因此僅適用於 Chromium 瀏覽器。如果在 Chromium 以外的瀏覽器中啟用,將顯示警告。

flakiness.metrics.retries

類型: number
預設: 1000

指標監控期間的重試次數。它會持續監控指定的影格數(1 個影格 = 16 毫秒),並確保指標穩定。

flakiness.retake.enabled

類型: boolean
預設: true

它會計算螢幕截圖影像的雜湊值,並透過確保影像沒有變更來檢查渲染內容的穩定性。

[!TIP]
對於 Chromium,通常單獨使用 flakiness.metrics.enabled 就足夠了。啟用此選項表示至少擷取兩次螢幕截圖,因此建議如果導致效能下降,則停用此選項。

flakiness.retake.interval

類型: number
預設: 100

再次嘗試擷取螢幕截圖之前的間隔(以毫秒為單位)。第二次擷取會立即執行以進行雜湊檢查。

flakiness.retake.retries

類型: number
預設: 10

重複擷取螢幕截圖的次數,直到影像的雜湊值相同為止。建議使用 3 或更大的值來達到重試的效果。

hooks

類型: ScreenshotHook[]
預設: []

用於中斷螢幕截圖擷取前後進程的 Hook。請指定一個實現以下介面的物件。

export type ScreenshotHook = {
  setup?: TestHook;
  preCapture?: TestHook;
  postCapture?: (
    page: Page,
    context: TestContext,
    image: ScreenshotImage,
  ) => Promise<void>;
};

每個都在以下生命週期中執行

方法 描述
setup 在執行 screenshot 函式後立即執行
preCapture 在執行 waitForPageReady 後執行
postCapture 在擷取螢幕截圖後,在儲存影像之前執行

像遮罩和移除這樣的內建函式是使用 Hook 實現的。

fullPage

類型: boolean
預設: true

請參閱 Page | Playwright

omitBackground

類型: boolean
預設: false

請參閱 Page | Playwright

scale

類型: 'css' | 'device'
預設: 'device'

請參閱 Page | Playwright

參數

這些是可以為每個 Story 指定的參數。

// Button.stories.tsx
const meta: Meta<typeof Button> = {
  component: Button,
  parameters: {
    screenshot: {
      /* parameters... */
    },
  },
};

export default meta;

skip

類型: boolean
預設: false

跳過螢幕截圖擷取。在您想使用 @storybook/test-runner 進行測試但停用螢幕截圖擷取的情況下很有用。

delay

類型: number
預設:

擷取螢幕截圖前的延遲(以毫秒為單位)。在完成基本穩定性檢查後等待。

mask

類型: string | { selector: string; color: string }
預設:

用矩形遮罩對應於 CSS 選擇器的元素。適用於隱藏每次渲染內容都會不可避免地不同的元素。

remove

類型: string
預設:

移除對應於 CSS 選擇器的元素。

變更日誌

請參閱 CHANGELOG.md

授權

MIT © reg-viz

reg-viz