はじめに
この記事では、Playwright の toHaveCSS というメソッドを使って CSS の自動テストを実装する方法やユースケースを記載します。
開発環境
開発環境は以下の通りです。
- Windows 11
- VSCode
- React 18.3.1
- Mantine 7.16.2
- TypeScript 5.5.2
- Playwright 1.50.1
事前準備
事前準備として、Playwright の利用設定を行います。
手順は公式ドキュメントや以下の記事に記載があります。
1. color
以下のコードでは、ボタンをクリックすると、背景色が変化します。
BackgroundColorChangingButton.tsx
import { FC, useState } from "react";
export const BackgroundColorChangingButton: FC = () => {
const [bgColor, setBgColor] = useState<"red" | "blue">("red");
return (
<button
style={{ backgroundColor: bgColor }}
onClick={() => setBgColor((prev) => (prev === "red" ? "blue" : "red"))}
>
Change Background Color
</button>
);
};
toHaveCSS の第1引数にチェック対象の CSS プロパティである background-color
、第2引数に値である rgb(255, 0, 0)
を渡します。
BackgroundColorChangingButton.spec.ts
import { test, expect } from "@playwright/test";
test("button should have correct background color", async ({ page }) => {
await page.goto(
"http://localhost:3000/playwright/to-have-css/background-color-changing-button"
);
const button = page.getByRole("button", { name: "Change Background Color" });
await expect(button).toHaveCSS("background-color", "rgb(255, 0, 0)");
await button.click();
await expect(button).toHaveCSS("background-color", "rgb(0, 0, 255)");
await button.click();
await expect(button).toHaveCSS("background-color", "rgb(255, 0, 0)");
});
2. border-color
上記の例の類型として、マウスオーバー時のボーダーの色の変化なども toHaveCSS を使ってチェックできます。
以下の例では、マウスオーバー時、ボーダーが赤色になります。
HoverButton.tsx
import { FC } from "react";
export const HoverButton: FC = () => {
return <button className="hover-button">Hover me</button>;
};
index.css
.hover-button {
border: 4px solid transparent;
background-color: white;
color: black;
cursor: pointer;
transition: background-color 0.3s ease;
}
.hover-button:hover {
border-color: red;
}
HoverButton.spec.ts
import { test, expect } from "@playwright/test";
test("button should change color on hover", async ({ page }) => {
await page.goto("http://localhost:3000/playwright/to-have-css/hover-button");
const button = page.getByRole("button");
await expect(button).toHaveCSS("border-color", "rgba(0, 0, 0, 0)"); // Transparent
await button.hover();
await expect(button).toHaveCSS("border-color", "rgb(255, 0, 0)");
await page.mouse.move(0, 0); // Moves the mouse away
await expect(button).toHaveCSS("border-color", "rgba(0, 0, 0, 0)");
});
3. opacity
FadeInText.tsx
import { FC } from "react";
export const FadeInText: FC = () => {
return <p className="fade-text">Hover over me</p>;
};
FadeInText.spec.ts
import { test, expect } from "@playwright/test";
test("text should fade in when hovered", async ({ page }) => {
await page.goto("http://localhost:3000/playwright/to-have-css/fade-in-text");
const text = page.getByText("Hover over me");
// Check initial opacity (faded)
await expect(text).toHaveCSS("opacity", "0.3");
// Hover over the text
await text.hover();
// Check full opacity
await expect(text).toHaveCSS("opacity", "1");
});
4. font-size
HeadingFontSize.tsx
import { FC } from "react";
export const HeadingFontSize: FC = () => {
return <h1 style={{ fontSize: "72px" }}>Heading</h1>;
};
HeadingSize.spec.ts
import { test, expect } from "@playwright/test";
test("heading should have correct font size", async ({ page }) => {
await page.goto(
"http://localhost:3000/playwright/to-have-css/heading-font-size"
);
await expect(page.getByRole("heading")).toHaveCSS("font-size", "72px");
});