webdriver-0.15.0.0: tests/TestLib/Mouse.hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE MultiWayIf #-}
module TestLib.Mouse (
assertWithinPixels
, getBoundingClientRect
, getElementCenter
, MouseEventType(..)
, MouseEvent(..)
, ClientRect(..)
) where
import Control.Monad.IO.Class
import Data.Aeson as A
import Data.String.Interpolate
import qualified Data.Text as T
import GHC.Generics
import Test.Sandwich
import Test.WebDriver
import TestLib.Types
data MouseEventType =
MouseEventTypeClick
| MouseEventTypeDoubleClick
| MouseEventTypeContextMenu
deriving (Show, Eq)
instance FromJSON MouseEventType where
parseJSON (String "click") = pure MouseEventTypeClick
parseJSON (String "dblclick") = pure MouseEventTypeDoubleClick
parseJSON (String "contextmenu") = pure MouseEventTypeContextMenu
parseJSON x = fail [i|Unexpected mouse event type: #{x}|]
data MouseEvent = MouseEvent {
eventType :: MouseEventType
, screenX :: Int
, screenY :: Int
, clientX :: Int
, clientY :: Int
, pageX :: Int
, pageY :: Int
, button :: Int
} deriving (Show, Eq, Generic, FromJSON)
data ClientRect = ClientRect {
bottom :: Double
, height :: Double
, left :: Double
, right :: Double
, top :: Double
, width :: Double
, x :: Double
, y :: Double
} deriving (Show, Eq, Generic, FromJSON)
assertWithinPixels :: (MonadIO m) => (Double, Double) -> (Double, Double) -> Double -> m ()
assertWithinPixels (x1, y1) (x2, y2) tolerance =
if | d <= tolerance -> return ()
| otherwise -> expectationFailure [i|Points were supposed to be within #{tolerance}, but distance was #{d}|]
where
d = sqrt ((x2 - x1)**2 + (y2 - y1)**2)
getBoundingClientRect :: (HasSession ctx) => T.Text -> ExampleT ctx IO ClientRect
getBoundingClientRect cssSelector =
executeJS [JSArg cssSelector] [i|return document.querySelector(arguments[0]).getBoundingClientRect()|]
getElementCenter :: (HasSession ctx) => T.Text -> ExampleT ctx IO (Double, Double)
getElementCenter cssSelector = do
ClientRect {..} <- getBoundingClientRect cssSelector
return (left + (width / 2.0), top + (height / 2.0))