Page Object PatternをベースにTestCafeでE2Eテストを作ってみた



以前のエントリでKotlinでSelenideを使ったE2Eテストを作ったときもPage Object Patternを利用して見通しの良いテストコードが書けました。TestCafeでも同様にPage Object Patternを利用することが推奨されています。今回はTestCafeでもPage Object Patternを利用してテストを書いてみました。

何をテストするか

次のサイトのログイン認証をテストします。FRESH!(フレッシュ) - 生放送がログイン不要・高画質で見放題テスト内容としては次のとおりです。

テストコードのフォルダ構成

プロジェクトのフォルダ構成は次のように役割ごとに整理しました。

1
2
3
4
5
tests
├── features
├── operators
├── pages
└── support

次からはTestCafeのAPIを利用して記述したコード例を紹介します。

Pageクラス

TestCafeのAPIを利用して認証画面のPageクラスを作ります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import { Selector } from 'testcafe';

export default class AuthPage {
    constructor () {

        this.url = 'https://freshlive.tv/auth/fresh_id';

        this.idInput = Selector('#user_id');
        this.pwInput = Selector('#password');

        this.submitBtn = Selector('button[type=submit]');
    }
}

これで認証画面の要素をまとめたAuthPageクラスができあがりました。

Operatorクラス

TestCafeのAPIを利用してOperatorクラスを作ります。
今回は認証画面でログイン認証する必要があるのでログイン操作をまとめます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import {t} from 'testcafe';
import AuthPage from '../../pages/auth/auth-page.js';

export default class AuthOperator {
    constructor () {
        this.page = new AuthPage();
    }

    async open() {
        await t
            .navigateTo(this.page.url)
    }

    async authorize(id, password) {
        await this.open();

        await t
            .typeText(this.page.idInput, id)
            .typeText(this.page.pwInput, password)
            .click(this.page.submitBtn)
    }
}

Supportクラス

TestCafeのAPIを利用してのSupportクラスを作ります。
今回は画面キャプチャを撮るユーティリティクラスを作りました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import {t} from 'testcafe';

export default class ScreenshotSupport {
    constructor () {
    }

    async take() {
        await t
            .takeScreenshot;
    }
}

Specクラス

TestCafeのAPIを利用してのSpecクラスを作ります。
このクラスでテスト内容をまとめていきます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { expect } from 'chai';

import HomePage from '../../pages/home/home-page.js';
import AuthOperator from '../../operators/auth/auth-operator.js';
import ScreenshotSupport from '../../support/screenshot-support.js';

const homePage = new HomePage();
const authOperator = new AuthOperator();
const screenshot = new ScreenshotSupport();

const userId = ' xxxxxxxx';
const password = 'xxxxxxxx';
const accountId = 'My Account';

fixture `auth fixtures`;

test('authorized at page then is appeared your account name on element of header.', async t => {

    // ログインする
    await authOperator.authorize(userId, password);

    // スクリーンショット撮る
    await screenshot.take();

    // ログイン後にHomeにリダイレクトをするのでURLが正しく切り替わっているか
    const docURI = await t.eval(() => document.documentURI);
    expect(docURI).eql(`${homePage.url}?&login_succeeded=true`);

    // ヘッダーメニューにログインしたアカウント名が表示されているか
    await t
        .expect(homePage.accountMenuDropdown.exists).eql(true)
        .expect(homePage.accountName.exists).eql(true)
        .expect(homePage.accountName.innerText).eql(accountId);
});

まとめ

ソースを公開しています

関連エントリ

WebDriver不要のTestCafeを使ったE2EテストをChatOpsに導入してみた - 平日インプット週末アウトプットぶろぐ