はじめに
【初心者向けワークショップ】Cloud9+Docker Compose+CypressでE2Eテストを書いてみよう!の記事でCypressを使ったE2Eのテストを書くワークショップの記事を書きました。
この記事では、こういう検証をしたい場合Cypressではどう書くのかを記していきます。
コマンド集は公式ドキュメントにもあります。
本記事ではその中からよく使いそうなこれだけはおさえておきたいものをピックアップして、要素の操作と検証など実践に使いやすい形のサンプルを用意してみました。
また、CypressのテストコードだけでなくHTMLも合わせて載せておりますので参考にしていただけたらと思います。
ページ遷移
以下、前提として baseUrlがcypress.jsonに定義されているものとします。
e2e/cypress.json
{"baseUrl":"http://localhost:8080","reporter":"junit","reporterOptions":{"mochaFile":"cypress/results/output.xml"}}cypress/integration/spec.js
it('open page',()=>{// ページ遷移(パスを指定)cy.visit('/')// Qiitaのページを開く(URLを指定)cy.visit('https://qiita.com')}要素の取得、要素の値を取得
要素の取得
cy.get('[セレクタ]')で要素を取得できます。
<divid='header'></div>it('Get element',()=>{cy.visit('/')// 要素の取得cy.get('#header')})親・子要素の取得
<ulclass='parent'><liclass='active child'>list1</li><liclass='child'>list2</li><liclass='child'>list3</li></ul>it('Get child and parent element',()=>{cy.visit('/')// 子要素の取得cy.get('ul').children('.active').should('have.text','list1')cy.get('ul').children().should('have.length',3)cy.task('log','== 子要素の取得 ==')cy.get('ul').children().each(($li,index,$list)=>{cy.task('log',$li.text())})// 親要素の取得cy.get('.child').parent().should('have.class','parent')※ ログの出力方法は、後述の ログの出力をご覧ください。
コンソールログ(抜粋)
apache | 172.20.0.3 - - [13/Sep/2020:05:05:16 +0000] "GET / HTTP/1.1" 200 254
cypress | == 子要素の取得 ==
cypress | list1
cypress | list2
cypress | list3
cypress |
cypress | (Results)
cypress |
ページタイトルの取得
cy.title()でページタイトルを取得できます。
要素の取得でも説明した通り、cy.get('title')でも取得できます。
<title>sample page title</title>it('Verify title',()=>{cy.visit('/')// ページタイトルを取得して検証するcy.title().should('eq','sample page title')cy.get('title').should('have.text','sample page title')})要素の操作
クリック、チェック操作
チェックボックスにチェックを入れたり、ラジオボタンを選択したりボタンをクリックすることができます。
<form><div><inputtype='checkbox'name='check'value='check_1'checked='checked'><inputtype='checkbox'name='check'value='check_2'></div><div><inputtype='radio'name='feedback'value='good'checked='checked'>良い
<inputtype='radio'name='feedback'value='bad'>悪い
</div></form><buttontype=buttononclick='alert("clicked button")'>Click here</button>it('Click or check an element',()=>{cy.visit('/')// 要素をチェックするcy.get('[value="check_1"]').check()// チェックボックスcy.get('[type="radio"]').first().check()// ラジオボタンの1番目// 要素をクリックするcy.get('[type="button"]').click()})入力操作
テキストボックスに文字の入力することができます。
また、入力されたテキスト内の文字を削除することもできます。
<textarea>hoge</textarea>it('Delete text and type text',()=>{cy.visit('/')// テキストエリアの文字列を検証(消去前)cy.get('textarea').should('have.value','hoge')// テキストエリアの文字を消去cy.get('textarea').clear()// テキストエリアの文字列を検証(消去後)cy.get('textarea').should('have.value','')// テキストエリアに文字を入力cy.get('textarea').type('Hello, World')// テキストエリアの文字列を検証(入力後)cy.get('textarea').should('have.value','Hello, World')})検証
要素の値の検証
cy.get('[セレクタ]').should('have.id')などhave.xxxで指定します。
また、cy.get('[セレクタ]').should('have.attr', '[属性名]', '[値]')でも各属性の値は取得できます。
<divclass='title'><divid='main_title'>Content title</div><divclass='sub_title'>Sub title</div></div><inputtype='number'name='numberbox'value='1'>it('Verify element values and attributes',()=>{cy.visit('/')// 要素のテキストを検証するcy.get('#main_title').should('have.text','Content title')// 要素のid属性の値を検証するcy.get('.title div:first-child').should('have.id','main_title')// 要素のclass属性の値を検証するcy.get('.title div:last-child').should('have.class','sub_title')// 要素のvalue属性の値を検証するcy.get('[name="numberbox"]').should('have.value','1')// 要素のtype属性の値を検証するcy.get('[name="numberbox"]').should('have.attr','type','number')// 要素のname属性の値を検証するcy.get('[type="number"]').should('have.attr','name','numberbox')})テキストの部分一致、完全一致の検証
<title>sample page title</title><divclass='title'><divid='main_title'>Content title</div><divclass='sub_title'>Sub title</div></div>it('Verify title',()=>{cy.visit('/')// ページタイトルを取得して検証する// 完全一致cy.title().should('eq','sample page title')cy.get('title').should('have.text','sample page title')// 部分一致cy.title().should('include','sample')cy.get('title').contains('sample')// ページ内のどこかに文字列が存在することを検証するcy.contains('Sub')})要素が表示されている・いないことの検証
<divclass='title'><divid='main_title'>Content title</div><inputtype='hidden'name='userid'value='12345'></div>it('Verify element display',()=>{cy.visit('/')// 要素が表示されていることを検証するcy.get('#main_title').should('be.visible')// 要素が表示されていないことを検証するcy.get('.title > input').should('not.be.visible')})ロケーションの取得
it('Get location',()=>{cy.visit('https://qiita.com')// ロケーションの取得cy.location().should((loc)=>{expect(loc.href).to.eq('https://qiita.com/')expect(loc.hostname).to.eq('qiita.com')expect(loc.pathname).to.eq('/')expect(loc.port).to.eq('')expect(loc.protocol).to.eq('https:')})})現在のページのURLの取得はcy.url()でも可能です。
it('Get current url',()=>{cy.visit('https://qiita.com')// URLの取得その1cy.location().should((loc)=>{expect(loc.href).to.eq('https://qiita.com/')})// URLの取得その2cy.url().should('eq','https://qiita.com/')})ログの出力
cypress/plugins/index.jsを以下のように編集します。
cypress/plugins/index.js
module.exports=(on,config)=>{on('task',{log(message){console.log(message)returnnull}})}cypress/integration/spec.js
it('Log',()=>{cy.visit('/')// ログの出力cy.task('log',"*** ログ開始 ***")cy.task('log',"hoge")cy.task('log',"fuga")cy.task('log',"*** ログ終了 ***")})Cypressのコンソールログ(抜粋)
cypress | Running: spec.js (1 of 1)
apache | 172.20.0.3 - - [13/Sep/2020:02:41:17 +0000] "GET / HTTP/1.1" 200 152
cypress | *** ログ開始 ***
cypress | hoge
cypress | fuga
cypress | *** ログ終了 ***
cypress |
cypress | (Results)
cypress |