module Test.WebDriver.Commands.ElementRetrieval (
  findElem
  , findElems
  , findElemFrom
  , findElemsFrom
  , activeElem

  , Selector(..)
  , Element(..)
  ) where

import Data.Aeson as A
import Data.Text (Text)
import GHC.Stack
import Test.WebDriver.Types
import Test.WebDriver.Util.Commands


-- | Find an element on the page using the given element selector.
findElem :: (HasCallStack, WebDriver wd) => Selector -> wd Element
findElem :: forall (wd :: * -> *).
(HasCallStack, WebDriver wd) =>
Selector -> wd Element
findElem = Method -> Text -> Selector -> wd Element
forall (wd :: * -> *) a b.
(HasCallStack, WebDriver wd, ToJSON a, FromJSON b) =>
Method -> Text -> a -> wd b
doSessCommand Method
methodPost Text
"/element"

-- | Find all elements on the page matching the given selector.
findElems :: (HasCallStack, WebDriver wd) => Selector -> wd [Element]
findElems :: forall (wd :: * -> *).
(HasCallStack, WebDriver wd) =>
Selector -> wd [Element]
findElems = Method -> Text -> Selector -> wd [Element]
forall (wd :: * -> *) a b.
(HasCallStack, WebDriver wd, ToJSON a, FromJSON b) =>
Method -> Text -> a -> wd b
doSessCommand Method
methodPost Text
"/elements"

-- | Search for an element using the given element as root.
findElemFrom :: (HasCallStack, WebDriver wd) => Element -> Selector -> wd Element
findElemFrom :: forall (wd :: * -> *).
(HasCallStack, WebDriver wd) =>
Element -> Selector -> wd Element
findElemFrom Element
e = Method -> Element -> Text -> Selector -> wd Element
forall (wd :: * -> *) a b.
(HasCallStack, WebDriver wd, ToJSON a, FromJSON b) =>
Method -> Element -> Text -> a -> wd b
doElemCommand Method
methodPost Element
e Text
"/element"

-- | Find all elements matching a selector, using the given element as root.
findElemsFrom :: (HasCallStack, WebDriver wd) => Element -> Selector -> wd [Element]
findElemsFrom :: forall (wd :: * -> *).
(HasCallStack, WebDriver wd) =>
Element -> Selector -> wd [Element]
findElemsFrom Element
e = Method -> Element -> Text -> Selector -> wd [Element]
forall (wd :: * -> *) a b.
(HasCallStack, WebDriver wd, ToJSON a, FromJSON b) =>
Method -> Element -> Text -> a -> wd b
doElemCommand Method
methodPost Element
e Text
"/elements"

-- | Return the element that currently has focus.
activeElem :: (HasCallStack, WebDriver wd) => wd Element
activeElem :: forall (wd :: * -> *). (HasCallStack, WebDriver wd) => wd Element
activeElem = Method -> Text -> Value -> wd Element
forall (wd :: * -> *) a b.
(HasCallStack, WebDriver wd, ToJSON a, FromJSON b) =>
Method -> Text -> a -> wd b
doSessCommand Method
methodGet Text
"/element/active" Value
Null

-- | Specifies element(s) within a DOM tree using various selection methods.
data Selector =
  ByCSS Text
  | ByLinkText Text
  | ByPartialLinkText Text
  | ByTag Text
  | ByXPath Text
  deriving (Selector -> Selector -> Bool
(Selector -> Selector -> Bool)
-> (Selector -> Selector -> Bool) -> Eq Selector
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Selector -> Selector -> Bool
== :: Selector -> Selector -> Bool
$c/= :: Selector -> Selector -> Bool
/= :: Selector -> Selector -> Bool
Eq, Int -> Selector -> ShowS
[Selector] -> ShowS
Selector -> String
(Int -> Selector -> ShowS)
-> (Selector -> String) -> ([Selector] -> ShowS) -> Show Selector
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Selector -> ShowS
showsPrec :: Int -> Selector -> ShowS
$cshow :: Selector -> String
show :: Selector -> String
$cshowList :: [Selector] -> ShowS
showList :: [Selector] -> ShowS
Show, Eq Selector
Eq Selector =>
(Selector -> Selector -> Ordering)
-> (Selector -> Selector -> Bool)
-> (Selector -> Selector -> Bool)
-> (Selector -> Selector -> Bool)
-> (Selector -> Selector -> Bool)
-> (Selector -> Selector -> Selector)
-> (Selector -> Selector -> Selector)
-> Ord Selector
Selector -> Selector -> Bool
Selector -> Selector -> Ordering
Selector -> Selector -> Selector
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Selector -> Selector -> Ordering
compare :: Selector -> Selector -> Ordering
$c< :: Selector -> Selector -> Bool
< :: Selector -> Selector -> Bool
$c<= :: Selector -> Selector -> Bool
<= :: Selector -> Selector -> Bool
$c> :: Selector -> Selector -> Bool
> :: Selector -> Selector -> Bool
$c>= :: Selector -> Selector -> Bool
>= :: Selector -> Selector -> Bool
$cmax :: Selector -> Selector -> Selector
max :: Selector -> Selector -> Selector
$cmin :: Selector -> Selector -> Selector
min :: Selector -> Selector -> Selector
Ord)

instance ToJSON Selector where
  toJSON :: Selector -> Value
toJSON Selector
s = case Selector
s of
    ByTag Text
t             -> Text -> Text -> Value
selector Text
"tag name" Text
t
    ByLinkText Text
t        -> Text -> Text -> Value
selector Text
"link text" Text
t
    ByPartialLinkText Text
t -> Text -> Text -> Value
selector Text
"partial link text" Text
t
    ByCSS Text
t             -> Text -> Text -> Value
selector Text
"css selector" Text
t
    ByXPath Text
t           -> Text -> Text -> Value
selector Text
"xpath" Text
t
    where
      selector :: Text -> Text -> Value
      selector :: Text -> Text -> Value
selector Text
sn Text
t = [Pair] -> Value
object [Key
"using" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
sn, Key
"value" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
t]