liguofeng29’s blog

個人勉強用ブログだっす。

groovy,geb(selenium),spockによる自動化テスト その6

gebでjavascriptを利用する

  1. javascript変数を取得
  2. メソッド呼び出し
  3. js追加

script6.html

<html>
<title>for javascript</title>
<script type="text/javascript">
   var var1 = 100;

   function add(a, b) {
       return a + b;
   }
</script>
<body>
</body>
</html>

script6_js.groovy

/**
 * Geb for javascript
 *
 * http://www.gebish.org/manual/
 *
 * 1. get variable from javascript
 * 2. call method
 * 3. add script
 */
import geb.Browser

def testPage = new File('src/main/java/html/script6.html')

Browser.drive {
    // 指定URLでブラウザオープン
    go testPage.toURI().toString()

    // JavascriptInterface geb.Browser.getJs()

    // get variable
    assert js.var1 == 100
    // 2. call method
    assert js.add(1, 10) == 11
    // 3. add script
    assert js."document.title" == "for javascript"
    js."alert('add script')"

    sleep 10 * 1000
}.quit()

f:id:liguofeng29:20170301210637g:plain

gebでpopupを制御する

SeleniumのWebDriverはalert, confirm, promptに対するソリューションを提供してないらしい。
gebでは、AlertAndConfirmSupporでalert,confirmに対する操作が可能。
※ promptはサポートしてないらしい。

API from AlertAndConfirmSuppor

  • alert

    • def withAlert(Closure actions)
    • def withAlert(Map params, Closure actions)
    • void withNoAlert(Closure actions) → 意図してない個所でalertが発生してするとAssertionError発生
  • confirm

    • def withConfirm(boolean ok, Closure actions)
    • def withConfirm(Closure actions)
    • def withConfirm(Map params, Closure actions)
    • def withConfirm(Map params, boolean ok, Closure actions)
    • void withNoConfirm(Closure actions)
/**
 * Geb for popup
 *
 * http://www.gebish.org/manual/
 *
 * use AlertAndConfirmSupport for alert,confirm,prompt
 *
 * Geb does not provide any support for prompt() due to its infrequent and generally discouraged use.

 */
import geb.Browser
import geb.Page

def testPage = new File('src/main/java/html/script7.html')

Browser.drive {
    // baseUrl設定
    config.baseUrl = new File(testPage.getAbsolutePath()).toURI()

    to PopupPage

    assert withAlert(wait: true) { showAlert.click() } == "alert!"
    //assert withAlert(wait: true) { showAlert.click() } == "some alert!" // エラー

    // actionsでalertが表示されるとAssertionError発生する
    withNoAlert { $("input", name: "dontShowAlert").click() }

    assert withConfirm(true) { showConfirm.click() } == "confirm?"
    sleep 2 * 1000
    assert withConfirm(false) { showConfirm.click() } == "confirm?"

    sleep 10 * 1000
}.quit()

class PopupPage extends Page{
    // baseURL +
    static url = "script7.html"
    static content = {
        showAlert      {$("input", name: "showAlert")}
        donotShowAlert {$("input", name: "dontShowAlert")}
        showConfirm    {$("input", name: "showConfirm")}
    }
}

f:id:liguofeng29:20170301211736g:plain

waitFor

Ajaxなので非同期処理の際に、処理完了を待つ際に使う。
geb.PageクラスのAPIである。

/**
 * Geb for waitFor
 * http://www.gebish.org/manual/
 * Ajaxなど処理待ちが発生する場合、waitForを利用して待つことができる
 *
 * API:
 *
 * waitFor {}           デフォルト
 * waitFor(10) {}       最長10秒待ち
 * waitFor(10, 0.5){}   最長10秒待ち、 0.5秒間隔
 * waitFor("quick"){}   GebConfig.groovyの設定
 *
 *
 * Geb does not provide any support for prompt() due to its infrequent and generally discouraged use.

 */
import geb.Browser

Browser.drive {
    go 'https://www.google.com/recaptcha/demo/ajax'

    $('input', value: 'Click Me').click()
    waitFor {
        $('#recaptcha_challenge_image').size() > 0
    }
    println $('#recaptcha_challenge_image').attr('src')

    sleep 10 * 1000
}.quit()

f:id:liguofeng29:20170301212218g:plain

WebAPI呼び出し

{
    "name": "Alex",
    "age": "20"
}
/**
 * Geb for calling api
 * http://www.gebish.org/manual/
 */
import geb.Browser
import groovy.json.JsonSlurper

def testPage = new File('src/main/java/json/json-data1.json')

Browser.drive {
    URL apiUrl = testPage.toURL()
    def data = new JsonSlurper().parseText(apiUrl.text)

    println data.name
    println data.age

    assert data.name == 'Alex'
    assert data.age == '20'

}.quit()

groovy,geb(selenium),spockによる自動化テスト その5

gebでframeを操作する方法

  1. 直接操作する
  2. Page Objectを利用する

script5.html

<html>
<body>
    <iframe name="header" src="script5_header_frame.html"></iframe>
    <iframe id="content" src="script5_content_frame.html"></iframe>
    <iframe id="footer" src="script5_footer_frame.html"></iframe>
</body>
</html>

script5_header_frame.html

<html>
<body>
    <span>HEADER</span>
</body>
</html>

script5_content_frame.html

<html>
<body>
    <div>CONTENT1</div>
    <div>CONTENT2</div>
    <div>CONTENT3</div>
</body>
</html>

script5_footer_frame.html

<html>
<body>
    <span>FOOTER</span>
</body>
</html>

script5_Geb_API_Frame.groovy

/**
 * Geb for Frame API
 *
 * http://www.gebish.org/manual/
 *
 * Frameを操作する方法
 * 1. 直接操作
 * 2. Page Object Model利用
 *
 */
import geb.Browser
import geb.Page

def testPage = new File('src/main/java/html/script5.html')

Browser.drive {
    // baseUrl設定
    config.baseUrl = new File(testPage.getAbsolutePath()).toURI()

    // 指定URLでブラウザオープン
    go testPage.toURI().toString()

    /** 1. 直接操作 ** **/
    // page.withFameと同価
    withFrame('header') {assert $('span').text() == 'HEADER' }
    withFrame('footer') {assert $('span').text() == 'FOOTER' }

    withFrame(0) { assert $('span').text() == 'HEADER' }
    withFrame(2) { assert $('span').text() == 'FOOTER' }

    withFrame($('#content')) { assert $('div', 2).text() == 'CONTENT3' }


    /** 2. Page Object **/
    to LayoutPage
    withFrame(contentsFrame) { println "contents frame内のdiv要素数 : " + ($('div').size()) }

    sleep 10 * 1000
}.quit()


class LayoutPage extends Page {
    // baseUrl + url
    static url = 'script5.html'

    static content = {
        contentsFrame(page: ContentsPage){$('#content')}
    }
}

class ContentsPage extends Page {
    // baseUrl + url
    static url = 'script5_content_frame.html'
}

console

contents frame内のdiv要素数 : 3

groovy,geb(selenium),spockによる自動化テスト その4

Geb API

form, input, checkbox, radioなどのHTMLElementの操作する

script4.html

<form id="form1">
    <div class="input1">
        <input name="username1" type="text" placeholder="input your name">
        <input name="password1" type="text" placeholder="input your password">
    </div>
    <div class="input2">
        <input name="username2" type="text" placeholder="input your name">
        <input name="password2" type="text" placeholder="input your password">
    </div>
        <div class="input3">
        <input name="username3" type="text" placeholder="input your name">
        <input name="password3" type="text" placeholder="input your password">
    </div>
</form>


<form id="form2">
    <input type="checkbox" name="checkbox1" value="single-check1"/>
    <input type="checkbox" name="checkbox2" value="single-check2"/>
</form>

<form id="form3">
    <input type="checkbox" name="multicheck" value="multi-check1"/>
    <input type="checkbox" name="multicheck" value="multi-check2"/>
    <input type="checkbox" name="multicheck" value="multi-check3"/>
</form>

<form id="form4">
    <input type="radio" name="sex" value="male" />
    <input type="radio" name="sex" value="female" />
</form>

<form id="form5">
    <input type="file" name="csvFile" />
</form>

<form id="form6">
    <select name="optionlist1">
        <option value="1">option1</option>
        <option value="2">option2</option>
        <option value="3">option3</option>
    </select>
    <select name="optionlist2">
        <option value="1">option1</option>
        <option value="2">option2</option>
        <option value="3">option3</option>
    </select>
</form>

script4_Geb_API.groovy

/**
 * Geb API
 *
 * http://www.gebish.org/manual/
 */
import geb.Browser

def testPage = new File('src/main/java/html/script4.html')

Browser.drive {
    // 指定URLでブラウザオープン
    go testPage.toURI().toString()

    /**************/
    /** for form **/
    /**************/
    // direct
    $('input', name: 'username1').value("ユーザ1")
    $('input', name: 'password1').value("パスワード1")

    // use shortcuts
    def form = $('#form1')
    form.username2 = "ユーザ2"
    form.password2 = "パスワード2"

    // use with
    $('#form1').with {
        username3 = 'ユーザ3'
        password3 = 'パスワード3'
    }

    // get value
    println ($('input', name: 'username1').value())
    println ($('#form1').password1)

    /******************/
    /** for checkbox **/
    /******************/
    // click and set value
    $('input', name: 'checkbox1').click()
    $('checkbox', name: 'checkbox1').value(true) // or false

    // click and set value with shortcut
    $('#form2').checkbox2().click()
    $('#form2').checkbox2().value(false)       // or true

    // get value
    println ($('input', name: 'checkbox1').value())
    println ($('#form2').checkbox2().value())


    /************************/
    /** for multi-checkbox **/
    /************************/
    $('#form3').multicheck = true // check all
    println ($('#form3').multicheck) // [multi-check1, multi-check2, multi-check3]

    /************************/
    /** for radio          **/
    /************************/
    $('#form4').sex = "female" // set
    println ($('#form4').sex)  // get female
    assert $('#form4').sex == 'female' // assert

    /************************/
    /** for input file     **/
    /************************/
    // need to set absolute path
    $('#form5').csvFile = new File("src/main/java/csv/data.csv").getAbsolutePath()
    // Or
    // $('input', name : 'csvFile').value('../csv/data.csv')

    /*************************/
    /** for drop-down select**/
    /*************************/
    $('select', name: 'optionlist1').value('2') // Or 'option2'

    // use shortcut
    $('#form6').optionlist2 = 'option3'
    // $('#form6').optionlist = 3

    // get value
    println ($('#form6').optionlist1) // print 2

    // assert
    assert $('#form6').optionlist2 == '3'

    sleep 10 * 1000

}.quit()

f:id:liguofeng29:20170301201129g:plain

groovy,geb(selenium),spockによる自動化テスト その3

Geb Navigator API

  • gebを使えば、jqueryのselectorに似ている書き方で要素page要素を取得することができる。

script3.html

<div>div1 text</div>
<div>div2 text</div>
<div class="search1">
    <form onsubmit="return bridge();">
        <input type="text" placeholder="input keyword" class="input" id="keyword" name="keyword">
        <br>
        <input type="button" value="search" class="submit" id="btnSearch" name="btnSearch" onclick="alert('clicked');">
    </form>
</div>

script3_navigator.groovy

/**
 * Geb Navigator API
 *
 * http://www.gebish.org/manual/current/#the-jquery-ish-navigator-api
 *
 * jquery selector
 * https://www.w3schools.com/jquery/trysel.asp
 * https://www.w3schools.com/jquery/jquery_selectors.asp
 *
 *
 */
import geb.Browser

def keywords = 'javait.hatenablog.com'
def testPage = new File('src/main\\java/html/script3.html')

Browser.drive {
    go testPage.toURI().toString()

// // search element by tag, class, id
//    $("div")
//    // Match the first "div" element on the page.
//    $("div", 0)
//    // Match all "div" elements with a title attribute value of "section".
//    $("div", title: "section")
//    // Match the first "div" element with a title attribute value of "section".
//    $("div", 0, title: "section")
//    // Match all "div" elements who have the class "main".
//    $("div.main")
//    // Match the first "div" element with the class "main".
//    $("div.main", 0)

    // search element by traversing
// <div class="a">
//     <div class="b">
//         <p class="c"></p>
//         <p class="d"></p>
//         <p class="e"></p>
//     </div>
//     <div class="f"></div>
// </div>

// assert $("p.d").previous() == $("p.c")
// assert $("p.e").prevAll() == $("p.c").add("p.d")
// assert $("p.d").next() == $("p.e")
// assert $("p.c").nextAll() == $("p.d").add("p.e")
// assert $("p.d").parent() == $("div.b")
// assert $("p.c").siblings() == $("p.d").add("p.e")
// assert $("div.a").children() == $("div.b").add("div.f")

    // by tag
    println "divタグ数 : " + $("div").size()
    println "2個目divタグのtext : " + $("div", 1).text()

    // by id
    $('#keyword').value(keywords)
    $('#btnSearch').click()

    sleep 10 * 1000

}.quit()

groovy,geb(selenium),spockによる自動化テスト その2

eclipseでGroovy ScriptでGebを利用する

  • eclipse4.6 http://mergedoc.osdn.jp/

  • groovy eclipse https://github.com/groovy/groovy-eclipse/wiki

  • buildship Gradle integration 2.0

  • gradleプロジェクト生成

  • build.gradleに依存関係追加
    dependencies {
    // for geb
    compile “org.gebish:geb-core:1.1.1”
    compile “org.seleniumhq.selenium:selenium-firefox-driver:3.1.0”
    compile “org.seleniumhq.selenium:selenium-support:3.1.0”
    }
  • scpirt1.groovy
/**
 * Geb sample
 *
 * http://www.gebish.org/manual/current/#the-jquery-ish-navigator-api
 *
 * jquery selector
 * https://www.w3schools.com/jquery/trysel.asp
 * https://www.w3schools.com/jquery/jquery_selectors.asp
 *
 *
 */
import geb.Browser

/**
 * geb常用メソッド
 *
 * .value() elementのtext代入
 * .text()  elementのtext取得
 * .click() elementのclick
 * waitFor    条件待ち、時間経過するとWaitTimeoutExceptionが発生する
 *
 */
def keyword = 'javait.hatenablog.com'

Browser.drive {
    go 'http://yahoo.co.jp'

    // タイトルがYahooになるまで待つ
    waitFor { title.startsWith('Yahoo') }

    // keyword入力
    $('#srchtxt').value(keyword)
    // ボタンクリック
    $($('#srchbtn')).click()

    // タイトルが検索結果で終わるまで待つ
    waitFor() { title.endsWith('検索') }

    // waitFor(1) { false } 1秒後timeout
    // waitFor { title.endsWith('設定した時間後timeoutが発生する') }

    // 出力
    $('h3').each { println "* ${it.text()}" }

}.quit()

f:id:liguofeng29:20170301201457g:plain