module Test.Hspec.WebDriver(
BrowserDefaults(..)
, it
, Using(..)
, pending
, pendingWith
, WdExpectation(..)
, shouldBe
, shouldBeTag
, shouldHaveText
, shouldHaveAttr
, shouldReturn
, shouldThrow
, createSessionManager
, createSessionManager'
, TestCapabilities(..)
, hspec
, Spec
, describe
, context
, parallel
, WD
, liftIO
, module Test.WebDriver.Commands
, withCaps
) where
import Control.Exception.Lifted (try, Exception)
import Control.Monad.IO.Class (liftIO)
import Data.Typeable (Typeable)
import Test.HUnit (assertEqual, assertFailure)
import Test.Hspec hiding (shouldReturn, shouldBe, shouldSatisfy, shouldThrow, it, pending, pendingWith)
import Test.Hspec.Core (Result(..), fromSpecList, SpecTree(..), Item(..), Params)
import Test.WebDriver hiding (Browser(..))
import Test.WebDriver.Commands
import qualified Test.WebDriver as W
import qualified Test.Hspec as H
import qualified Data.Text as T
import Test.Hspec.WebDriver.Internal
data BrowserDefaults = Firefox | Chrome | IE | Opera | IPhone | IPad | Android
deriving (Eq, Show, Enum, Bounded, Typeable)
instance TestCapabilities BrowserDefaults where
matchesCaps Firefox (Capabilities { browser = W.Firefox _ _ _ }) = True
matchesCaps Chrome (Capabilities { browser = W.Chrome _ _ _ _ }) = True
matchesCaps IE (Capabilities { browser = W.IE _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ }) = True
matchesCaps Opera (Capabilities { browser = W.Opera _ _ _ _ _ _ _ _ _ _ _ _ }) = True
matchesCaps IPhone (Capabilities { browser = W.IPhone}) = True
matchesCaps IPad (Capabilities { browser = W.IPad }) = True
matchesCaps Android (Capabilities { browser = W.Android }) = True
matchesCaps _ _ = False
newCaps Firefox = return $ defaultCaps { browser = firefox }
newCaps Chrome = return $ defaultCaps { browser = chrome }
newCaps IE = return $ defaultCaps { browser = ie }
newCaps Opera = return $ defaultCaps { browser = opera }
newCaps IPhone = return $ defaultCaps { browser = iPhone }
newCaps IPad = return $ defaultCaps { browser = iPad }
newCaps Android = return $ defaultCaps { browser = android }
data WdExpectation cap = WdTest [cap] (WD ())
| WdPending (Maybe String)
evaluateWd :: (Show cap, TestCapabilities cap) => WdExpectation cap -> [(String,Params -> (IO () -> IO ()) -> IO Result)]
evaluateWd (WdPending msg) = [("", \_ _ -> return $ Pending msg)]
evaluateWd (WdTest cs test) = map mkItem cs
where
mkItem c = ("using " ++ show c, eval c)
eval :: TestCapabilities c => c -> params -> (IO () -> IO ()) -> IO Result
eval c _ action = do action (runWD defaultSession $ withCaps c test)
return Success
class Using a where
type UsingCapabilities a :: *
using :: a -> WD () -> WdExpectation (UsingCapabilities a)
instance Using BrowserDefaults where
type UsingCapabilities BrowserDefaults = BrowserDefaults
using d = WdTest [d]
instance Using [BrowserDefaults] where
type UsingCapabilities [BrowserDefaults] = BrowserDefaults
using = WdTest
it :: (Show cap, TestCapabilities cap) => String -> WdExpectation cap -> Spec
it msg a = spec
where
mkItem m f = SpecItem Item { itemIsParallelizable = False
, itemRequirement = m
, itemExample = f
}
spec = case evaluateWd a of
[] -> fromSpecList []
[("",f)] -> fromSpecList [mkItem (msg) f]
[(m,f)] -> fromSpecList [mkItem (msg ++ " " ++ m) f]
ss -> describe msg $ fromSpecList $ map (uncurry mkItem) ss
pending :: WdExpectation ()
pending = WdPending Nothing
pendingWith :: String -> WdExpectation ()
pendingWith = WdPending . Just
shouldBe :: (Show a, Eq a) => a -> a -> WD ()
x `shouldBe` y = liftIO $ x `H.shouldBe` y
shouldBeTag :: Element -> T.Text -> WD ()
e `shouldBeTag` name = do
t <- tagName e
liftIO $ assertEqual ("tag of " ++ show e) name t
shouldHaveText :: Element -> T.Text -> WD ()
e `shouldHaveText` txt = do
t <- getText e
liftIO $ assertEqual ("text of " ++ show e) txt t
shouldHaveAttr :: Element -> (T.Text, T.Text) -> WD ()
e `shouldHaveAttr` (a, txt) = do
t <- attr e a
liftIO $ assertEqual ("attribute " ++ T.unpack a ++ " of " ++ show e) (Just txt) t
shouldReturn :: (Show a, Eq a) => WD a -> a -> WD ()
action `shouldReturn` expected = action >>= (\a -> liftIO $ a `H.shouldBe` expected)
shouldThrow :: (Show e, Eq e, Exception e) => WD a -> e -> WD ()
shouldThrow w expected = do
r <- try w
case r of
Left err -> err `shouldBe` expected
Right _ -> liftIO $ assertFailure $ "did not get expected exception " ++ show expected