Cypressの導入方法&簡単なE2Eテスト実施まで

Cypressの導入方法&簡単なE2Eテスト実施までを備忘録も兼ねて記載します。

## 導入方法
テストを実施したいディレクトリで以下コマンドを実施します。
※Cypressは開発する環境ごとにインストールすることが推奨されています。
```
npm install cypress
```
※Cypressの言語はJavaScriptなのでnode.jsが必要になります。

インストールが完了したら次に下記コマンドを実施します。
```
npx cypress open
```
コマンドを実施する以下の画面が表示されますので、画像の赤枠部分をクリックしてください。
![Screenshot_246.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717487/ddf304ba-d5be-ea5c-de9f-2e3dc4a5d9c4.png)

![Screenshot_247.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717487/6c3122fe-d419-df2c-cf87-31075b07a8c6.png)

![Screenshot_248.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717487/1be7e3ca-569e-8e5d-374a-fe970b1979ea.png)

上記まで進行すると以下の画面がchromeで開かれます。
左側の赤枠部分を押下するcypressの見本データが作成されるので今回は左側を選択して進めます。
![Screenshot_249.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717487/ef0b75c3-1258-878f-6e5f-1e6ce9c7bab9.png)

![Screenshot_252.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717487/34a356e1-a870-8aca-ac3f-4db3b31d61b3.png)

![Screenshot_251.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717487/39a301cf-7571-ad2d-35a2-9a18945acc54.png)
上記画面まで来れば導入は完了になります。

## 簡単なE2Eテスト実施
今回実施するE2Eテストのシナリオは下記になります。
```E2Eテストシナリオ
AZITOウェブサイトに遷移
TOPページから「システム開発」を選択して遷移
システム開発ページのスクリーンショットを撮影
```

実行ファイル作成
Cypressをインストールするために作成したフォルダーでの「e2e」より下のディレクトリに
実行ファイルを作成してください。
※今回は「AZITO.cy.js」で作成します。

作成した実行ファイルをvisual studio codeなどのツールで開いてください。
開いたら先ずはAZITOウェブサイトを開くところまでを下記の内容で記載します。
```AZITO.cy.js
describe("Test Suite", function(){
	it("Test 01", function(){
    
    // 表示サイズ変更
    cy.viewport(1920,1080)

	// AZITOウェブサイトに遷移
	cy.visit("https://www.azito.co.jp/")
     
	});
});
```
※表示サイズの値を変更すればスマホ表示も可能です。

一旦、こちらで実行をしてみましょう。
実行は以下画面で実行したいファイルをクリックすると行われます。
![Screenshot_264.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717487/ec843e56-4f0d-eeeb-7aaf-79ca423fb6de.png)



実行すると以下の画面のようにAZITOウェブサイトのTOPページへ遷移することが確認出来ます。
※左側に実行状況が出るのでエラーがある場合は参考にしてください。
![Screenshot_263.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717487/69405ce2-f148-fef4-3cd7-c21f3566ab2c.png)

※この画面のままで実行ファイルが保存されると自動でテストが実行されます。

次にを下記の内容を追加します。
```AZITO.cy.js
	// 事業内容から「システム開発」を選択して遷移
	cy.contains('事業内容') // DOM取得_文字列「事業内容」を取得
	.click() // クリック
	cy.contains('システム開発') // DOM取得_文字列「システム開発」を取得
	.click() // クリック
```
※クリックは表示されていないと実行できないので直接「システム開発」のクリックはできないです。

実行すると システム開発ページまで遷移します。
最後にスクリーンショットを撮影までを下記内容で追加します
```AZITO.cy.js
	// システム開発ページのスクリーンショットを撮影
	cy.scrollTo('bottom' ,{ duration: 2000 }) // ページの一番下まで2秒間でスクロール
	cy.wait(3000) // 3秒待ちます 
	cy.get('header').invoke('css', 'position', 'absolute') //ヘッダーの固定
	cy.screenshot() // スクリーンショット
	cy.get('header').invoke('css', 'position', null) //ヘッダーの固定解除
```
※スクロールに合わせて読み込み要素があるので下までスクロールを指定します。
※スクロールが早すぎると読み込みがされないので[duration]でスクロール速度を調整します。
※Cypressでのスクリーンショットはviewport分スクロールをしてスクリーンショットを撮り、それを繋ぎ合わせるのでヘッダーを固定しないと複数写ってしまいます。

実行すると以下のように画面全体のスクリーンショットが取得出来ます。
![Test Suite -- Test 01 (34).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717487/3419382c-a797-c060-5ed6-272e39e9b501.png)


▼今回のソース全体版
```AZITO.cy.js
describe("Test Suite", function(){
	it("Test 01", function(){
    
    // 表示サイズ変更
    cy.viewport(1920,1080)

	// AZITOウェブサイトに遷移
	cy.visit("https://www.azito.co.jp/")

	// 事業内容から「システム開発」を選択して遷移
	cy.contains('事業内容') // DOM取得_文字列「事業内容」を取得
	.click() // クリック
	cy.contains('システム開発') // DOM取得_文字列「システム開発」を取得
	.click() // クリック

	// システム開発ページのスクリーンショットを撮影
	cy.scrollTo('bottom' ,{ duration: 2000 }) // ページの一番下まで2秒間でスクロール
	cy.wait(3000) // 3秒待ちます 
	cy.get('header').invoke('css', 'position', 'absolute') //ヘッダーの固定
	cy.screenshot() // スクリーンショット
	cy.get('header').invoke('css', 'position', null) //ヘッダーの固定解除
     
	});
});
```

## おまけ
スマホ表示で同じシナリオをした場合に同じソースでは上手く行かなかったので、
スマホ表示版に修正したソースコードを記載します。

```AZITO_SP.cy.js
describe("Test Suite", function(){
	it("Test 01", function(){
    
    // 表示サイズ変更
    cy.viewport(750,1334)

	// AZITOウェブサイトに遷移
	cy.visit("https://www.azito.co.jp/")

	// メニューから「システム開発」を選択して遷移
	cy.get('[class="menu_trig menu_open"]') // DOM取得_メニューアイコンのclassを取得
	.click() // クリック
	cy.get('[class="menu_offset"]') // DOM取得_メニュー内の「システム開発」のclassを取得
	.eq(1)  //[menu_offset]は複数あるので2個目を取得
	.click() // クリック

	// システム開発ページのスクリーンショットを撮影
	cy.scrollTo('bottom' ,{ duration: 2000 }) // ページの一番下まで2秒間でスクロール
	cy.wait(3000) // 3秒待ちます 
	cy.get('header').invoke('css', 'position', 'absolute') //ヘッダーの固定
	cy.get('[class="contact_trig"]').invoke('css', 'position', 'absolute') //メールアイコンの固定
	cy.get('[class="menu_trig menu_open"]').invoke('css', 'position', 'absolute') //メニューアイコン(開く)を固定
	cy.get('[class="menu_trig menu_close"]').invoke('css', 'position', 'absolute') //メニューアイコン(閉じる)を固定
	cy.screenshot() // スクリーンショット
	cy.get('header').invoke('css', 'position', null) //ヘッダーの固定解除
	cy.get('[class="contact_trig"]').invoke('css', 'position', 'absolute') //メールアイコンの固定解除
	cy.get('[class="menu_trig menu_open"]').invoke('css', 'position', null) //メニューアイコン(開く)を固定解除
	cy.get('[class="menu_trig menu_close"]').invoke('css', 'position', null)//メニューアイコン(閉じる)を固定解除

	});
});
```
※スマホ表示だとメニューアイコンからの遷移になるので[ontains]ではなく[get]でclassを指定する方法に変更
※メールアイコンとメニューアイコンがheader指定だと固定できないのでそれぞれのclassを指定する必要がありました。