ドメイン一括検索機能の要件定義とQA観点
ドメイン検索は入力欄と結果一覧だけに見えるが、実際には複数TLD、非同期応答、公開レコード、価格、最終確認という異なる責務を含む。本稿は公開UIから考える要件・テスト整理であり、特定サービスのソースコード解析ではない。
要件を分離する
Check Domain の公開説明では、対応拡張子を登録局RDAPで確認し、可用性、WHOIS/RDAPレコード、登録・更新価格を別々に扱っている。同種機能でも一つの「結果」へ潰さず、表示契約を分ける。
| 領域 | 必須情報 | 不明時の扱い |
|---|---|---|
| 可用性 | FQDN、状態、確認時刻、出典 | 要確認またはエラー |
| 公開レコード | レジストラ、日付、NS、出典 | 非公開・未取得を区別 |
| 価格 | 登録、更新、通貨、取得時刻 | 0円にしない |
| 外部遷移 | 登録会社、再確認文言 | 予約済みと表現しない |
状態遷移をテスト可能にする
複数TLDは行単位で状態を持つ。全件成功まで画面を固定せず、完了した行を読めるようにする。失敗応答を「取得済み」と解釈してはいけない。
type RowState =
| { kind: "loading" }
| { kind: "available"; checkedAt: string }
| { kind: "registered"; checkedAt: string }
| { kind: "confirm"; reason: string }
| { kind: "error"; retryable: boolean };
この型は説明用であり、実在DOMやAPI仕様を示すものではない。
E2Eテストの例
domain name search と同様の一括検索を実装する場合、可用性だけでなく不確実性の表示を検証する。
test("一部失敗でも完了行を保持する", async ({ page }) => {
// セレクタとレスポンスは対象アプリの仕様に合わせて置き換える
await page.getByRole("textbox", { name: /domain/i }).fill("northstar");
await page.getByRole("button", { name: /search/i }).click();
await expect(page.getByText(/available|registered/i).first()).toBeVisible();
await expect(page.getByText(/retry|confirm/i).first()).toBeVisible();
});
QAチェックリスト
- 裸の名前と完全なドメインを正規化できる
- 大文字小文字、前後空白、国際化ドメインを定義する
- 一行のタイムアウトが全件を壊さない
- 再検索時に古いレスポンスを捨てる
- 登録価格と更新価格を取り違えない
- 価格欠損を0円表示しない
- 公開連絡先の欠損を未所有と解釈しない
- 色だけに依存せず状態を表示する
- キーボード操作時に行追加でフォーカスを奪わない
- 登録会社の決済画面で最終確認する旨を表示する
境界条件を仕様に書く
検索結果は予約ではなく、最終可用性はチェックアウト時点で変わり得る。価格も変動する。さらに、ドメインの空き状況と商標上の利用可否は別問題である。
この境界を脚注に追いやらず、外部遷移の直前に明示する。QAの目的は「必ず買える」ことを保証するのではなく、どの証拠を見て、何を次に確認するかを利用者が理解できる状態を保証することにある。