cakephp3のテストでassertが足りなかったので追加してみた

CakePHP3で作ったサービスをPHPUnitとseleniumでテストしていたがやりたいassertが無かったので色々追加してみた
あとよく使うやつもついでにまとめてみた
テストクラスの親クラスとして定義したものに突っ込めば幸せになれるはず...？
他にも便利なのあったら教えてください。

## 良く使う関数

```php:getリクエスト送信
    /**
     * getリクエスト送信
     *
     * @param string $url url
     * @return \Facebook\WebDriver\Remote\RemoteWebDriver
     */
    public function sendGetRequest(string $url = '') {
        return $this->driver->get($this->hostURL . $url);
    }
```
selenium経由でgetリクエストを送りたいときによく使う
`$this->hostURL`はテスト対象のホスト(例 : http://localhost:8080)

```php:要素取得(単体)
    /**
     * 要素取得
     *
     * @param string $xpath xpath
     * @return \Facebook\WebDriver\Remote\RemoteWebElement|boolean 結果
     */
    public function getElement(string $xpath = '') {
        try {
            $element = $this->driver->findElement(WebDriverBy::xpath($xpath));
            return $element;
        } catch ( InvalidSelectorException $e ) {
        } catch ( NoSuchElementException $e ) {
        }
        return false;
    }
```
`findElement`を毎回書くのはめんどくさかったので
あとテストかいてるときに思ったけど基本的にxpath以外を使わなかったし、`findElement`使うと要素なかった時にエラー出すのが嫌だったのでこんな感じにした

```php:要素取得(複数)
    public function getElementList(string $xpath = '') {
        try {
            $element = $this->driver->findElements(WebDriverBy::xpath($xpath));
            return $element;
        } catch ( InvalidSelectorException $e ) {
        } catch ( NoSuchElementException $e ) {
        }
        return array();
    }
```
上記`getElement`の複数版
あと、`findElement`と`findElements`みたいに「s」つけるかどうかで分けていると打ち間違いしそうなので「List」をよく付ける

## Assert

```php
    /**
     * assert 要素の存在確認
     *
     * @param string $expected xpath
     * @param string $message
     */
    public function assertExistElement(string $expected, string $message) {
        $actual = $this->getElement($expected);
        $this->assertNotEquals(false, $actual, $message);
    }

    /**
     * assert 要素の非存在確認
     *
     * @param string $expected xpath
     * @param string $message
     */
    public function assertNotExistElement(string $expected, string $message) {
        $actual = $this->getElement($expected);
        $this->assertEquals(false, $actual, $message);
    }

    /**
     * assert 要素のタグ確認
     *
     * @param string $expected タグ名
     * @param string $actual xpath
     * @param string $message
     */
    public function assertEqualsElementTag(string $expected, string $actual, string $message) {
        $this->assertExistElement($actual, $message);
        $element = $this->getElement($actual);
        $this->assertEquals($expected, $element->getTagName(), $message);
    }

    /**
     * assert 要素のクラス存在確認
     *
     * @param string $expected クラス名
     * @param string $actual xpath
     * @param string $message
     */
    public function assertElementHasClass(string $expected, string $actual, string $message) {
        $this->assertExistElement($actual, $message);
        $element = $this->getElement($actual);
        $classString = $element->getAttribute('class');
        $classList = explode(' ', $classString);
        $this->assertContains($expected, $classList, $message);
    }

    /**
     * assert 入力要素のvalue確認
     *
     * @param string $expected value期待値
     * @param string $actual xpath
     * @param string $message
     */
    public function assertEqualsInputElementValue(string $expected, string $actual, string $message) {
        $inputTagList = array(
                'input',
                'select',
                'textarea'
        );

        $this->assertExistElement($actual, $message);
        $element = $this->getElement($actual);
        // タグ名の確認
        $this->assertContains($element->getTagName(), $inputTagList, $message);

        $value = $element->getAttribute('value');
        $this->assertEquals($expected, $value, $message);
    }

    /**
     * assert 表示テキスト確認
     *
     * @param string $expected テキスト
     * @param string $actual xpath
     * @param string $message
     */
    public function assertEqualsElementText(string $expected, string $actual, string $message) {
        $this->assertExistElement($actual, $message);
        $element = $this->getElement($actual);
        $this->assertEquals($expected, $element->getText(), $message);
    }

    /**
     * assert 要素表示状態確認
     *
     * @param bool   $expected 表示状態(true :表示、false : 非表示)
     * @param string $actual xpath
     * @param string $message
     */
    public function assertElementVisible(bool $expected, string $actual, string $message) {
        $this->assertExistElement($actual, $message);
        $element = $this->getElement($actual);
        $this->assertEquals($expected, $element->isDisplayed(), $message);
    }

    /**
     * assert URL確認
     *
     * @param string $expected URL
     * @param string $message
     */
    public function assertEqualsUrl(string $expected, string $message) {
        $actual = $this->driver->getCurrentURL();
        if(preg_match("/^\//", $expected)) {
            $expected = $this->hostURL . $expected;
        }
        $this->assertEquals($expected, $actual, $message);
    }

    /**
     * assert checkbox状態確認
     *
     * @param string $expected 選択状態(true :選択、false : 未選択)
     * @param string $actual xpath
     * @param string $message
     */
    public function assertCheckboxSelectStatus(bool $expected, string $actual, string $message) {
        $this->assertExistElement($actual, $message);
        $element = $this->getElement($actual);
        $this->assertEquals($expected, $element->isSelected(), $message);
    }

    /**
     * assert DB存在確認
     *
     * @param string $expected id
     * @param string $actual 対象テーブル名
     * @param string $message
     */
    public function assertExistTableData(string $expected, string $actual, string $message) {
        $table = TableRegistry::get($actual);
        $this->assertTrue($table->exists(array('id' => $expected)));
    }

    /**
     * assert DB更新確認
     *
     * @param string $expected id
     * @param string $actual 対象テーブル名
     * @param string $message
     */
    public function assertUpdateTableData(string $expected, string $actual, string $message) {
        $table = TableRegistry::get($actual);
        $this->assertExistTableData($expected, $actual, $message);
        $data = $table->get($expected);
        $nowTimeInt = intval(static::$nowTime->i18nFormat('yyyyMMddHHmmss'));
        $modifiedTimeInt = intval($data->modified->i18nFormat('yyyyMMddHHmmss'));
        $this->assertTrue(($nowTimeInt <= $modifiedTimeInt), $message);
    }

    /**
     * assert フラッシュメッセージ確認
     *
     * @param string $expected メッセージ内容
     * @param string $actual フラッシュ種別(info, success, warning, danger)
     * @param string $message
     */
    public function assertFlashMessage(string $expected, string $actual, string $message) {
        $this->assertExistElement("/html/body/div[contains(@class, 'alert-dismissible')][contains(@class, 'alert-${actual}')]", $message);
        $element = $this->getElement("/html/body/div[contains(@class, 'alert-dismissible')][contains(@class, 'alert-${actual}')]");
        $text = str_replace("×\n", "", $element->getText());
        $this->assertEquals($expected, $text, $message);
    }
```