Skip to content

Instantly share code, notes, and snippets.

@PhilOwen
Created December 4, 2016 12:45
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PhilOwen/9865e80a7f7735ed84fd8d02cc2cffb1 to your computer and use it in GitHub Desktop.
Save PhilOwen/9865e80a7f7735ed84fd8d02cc2cffb1 to your computer and use it in GitHub Desktop.
SeleniumをHaskellから

SeleniumのHaskell版で、ブラウザアプリをテストしてみる。
テスト対象は、以前に作っていた Backbone.jsでModelとViewを使ってみるで、 テストフレームワークにはHspecを使った。

SeleniumとHspecを連携させるには、 hspec-webdriverというパッケージがあった。 が、サンプルが動かなかったり残念だったので、 つなぎの部分は自分で何とかした。
手続き的なので、あまりHaskellっぽい簡潔な感じにはなっていない。

テスト対象は、Backbone.jsを使ったシングルページアプリ。 ユーザの入力に対し、JS上でイベントが処理されて 最終的に描画されるにはわずかに時間がかかる。
今回のテストでは、一番目のテストは おそらくそれが原因で失敗している。 失敗するときのスクリーンショットを見ると、 確かに変更が反映されていない。 回避するには、waitUntilなどでJSの処理を待てばいいはずだが、 あまりうまくないのでそのままにした (テストされる側も、テストしやすいようにしておけばよかった)。

なお、hs-webdriverのパッケージだけでは テスト中にブラウザを起動できない。 Seleniumのスタンドアロンサーバを立てて、 これにブラウザを操作させる必要がある。
Homebrewにはselenium-server-standaloneという パッケージがあるので、インストールして起動しておくこと。

References

name: hello-selenium
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.20
library
exposed-modules: Lib
build-depends: base
default-language: Haskell2010
test-suite hello-selenium-test
type: exitcode-stdio-1.0
main-is: Spec.hs
build-depends: base
, webdriver
, hspec
, text
, time
default-language: Haskell2010
module Lib where
{-# LANGUAGE OverloadedStrings #-}
import Test.Hspec
import Test.WebDriver
import Data.Time
import Data.Text(unpack)
import Text.Printf
config :: WDConfig
config = useBrowser chrome defaultConfig
main :: IO ()
main = hspec $ do
describe "Home page" $ do
it "should have a p element to show the last stroked key" $ do
text <- runSession config $ do
openPage "http://localhost:8000"
textInput <- findElem $ ByCSS "input[type='text']"
sendKeys "hello selenium" textInput
p <- findElem $ ByCSS "p"
text <- getText p
saveScreenshot "screenshot.png"
closeSession
return text
(unpack text) `shouldBe` "m"
it "should see 501 error on Console" $ do
msg <- runSession config $ do
openPage "http://localhost:8000"
textInput <- findElem $ ByCSS "input[type='text']"
sendKeys "hello selenium" textInput
logs <- getLogs "browser"
closeSession
return $ logMsg $ logs !! 1
(unpack msg) `shouldContain` "501"
it "should have the current time in its h1 element after clicking the button" $ do
title <- runSession config $ do
openPage "http://localhost:8000"
button <- findElem $ ByCSS "button"
click button
h1 <- findElem $ ByCSS "h1"
text <- getText h1
closeSession
return text
cs <- getCurrentHM
(unpack title) `shouldContain` cs
getCurrentHM :: IO String
getCurrentHM = do
time <- getCurrentTime
timeZone <- getCurrentTimeZone
let localTime = localTimeOfDay $ utcToLocalTime timeZone time
(h, m) = (todHour localTime, todMin localTime)
return $ printf "%02d:%02d" h m
resolver: lts-7.12
packages:
- '.'
extra-deps: []
flags: {}
extra-package-dbs: []
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment