Selenium Webdriver(wd)でselect boxとかのdata取得

Selenium Webdriverのnode.js bindingのwdを使ってselect box等のデータを取得するというメモ。 例えば、select boxなら<option value=xxx>hogehoge</option>のhogehogeの部分を取得したいとか。

というわけで、Yahooの路線検索にあるセレクトボックスから年の部分を取ってみたいと思います。↓ですね。 f:id:masami256:20150422232849p:plain

ソースはこれです。

"use strict";

var wd = require("wd");

require('colors');
var chai = require("chai");
var chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);
var should = chai.should();
chaiAsPromised.transferPromiseness = wd.transferPromiseness;

var async = require('async');

describe("Select box test", function () {
  this.timeout(300000);
  var driver;

  before(function () {
    var serverConfig = {
      host: 'localhost',
      port: 4444
    };

    driver = wd.promiseChainRemote(serverConfig);

    var desired = {
      browserName: 'chrome',
    };
    return driver.init(desired);
  });

  after(function (done) {
    console.log('finish');
    driver.quit().nodeify(done);

  });

  it("路線検索にある年のセレクトボックスから表示している文字列を取得", function(done) {
    return driver
        .get('http://www.yahoo.co.jp')
        .waitForElementByLinkText('路線')
          .click()
        // 日時指定の年のセレクトボックスを選択
        // このセレクトボックス内のoptionタグにアクセスするのでコールバック関数を渡し、その中で処理する
        // elがセレクトボックスのオブジェクト
        .waitForElement('id', 'y', 2000, 100, function (err, el) {
          // セレクトボックのオブジェクトからタグ名がoptionのものを選択
          // これもコールバック関数で要素を受け取る  
          el.elementsByTagName('option', function (err, elements) {
            // element.text()を使うのでasyncを使わないといけない
            async.forEach(elements, function(element, next1) {
              // text()の受け取って処理するためにここもasyncを使う
              async.series([function(next2) {
                // 1option要素に設定されている表示文字列をtext()で取得。
                element.text(function(err, text) {
                  // 表示文字列をコンソール出力    
                  console.log(text);
                  next2();
                });
              }], function complete(err, results) {
                next1();
              });
            }, function complete(err, results) {
              done();
            });
          });
        });
  });

});

やっていることとしては、waitForElement()で年のセレクトボックスを選択。今回はこのオブジェクトが必要なのでコールバック関数を使ってelという名前で受け取ります。 次はoptionを見ていくので引数で渡ってきたelを使ってelementsByTagName()を実行します。これもコールバック関数でオブジェクト(elements)を受け取ります。 次にasyncのforEach()でelementsを処理していきます。async.forEach()で1つずつelementを見ていきます。 表示されている文字を取るにはelement.text()です。valueを取るならelement.value()です。これも同期的には使えないのでasync.series()を使って、これのタスクとしてelement.text()を呼ぶようにしています。そして、element.text()のコールバック内でconsole.log()でやっと出力できます( ´∀`)bグッ!

実行するとこんな感じです。

masami@zen:~/app-test$ mocha ./selectbox-specs.js 


  Select box test
2014年
2015年
2016年
    ✓ 路線検索にある年のセレクトボックスから表示している文字列を取得 (5403ms)
finish


  1 passing (8s)

masami@zen:~/app-test$ 

面倒ですねorz

実践 Selenium WebDriver

実践 Selenium WebDriver