module Test.Marionette.Selector where

import Data.Aeson.KeyMap qualified as Object
import Data.Aeson.Types
import Data.Hashable (Hashable)
import Data.Text (Text)
import GHC.Generics (Generic)
import Test.Marionette.Element (Element (..), Shadow (..))
import Prelude

-- | Specifies element(s) within a DOM tree using various selection methods.
data Selector
    = ById Text
    | ByName Text
    | -- | (Note: multiple classes are not allowed. For more control, use 'ByCSS')
      ByClass Text
    | ByTag Text
    | ByLinkText Text
    | ByPartialLinkText Text
    | ByCSS Text
    | ByXPath Text
    | Anon Text
    | AnonAttribute Text
    deriving stock ((forall x. Selector -> Rep Selector x)
-> (forall x. Rep Selector x -> Selector) -> Generic Selector
forall x. Rep Selector x -> Selector
forall x. Selector -> Rep Selector x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Selector -> Rep Selector x
from :: forall x. Selector -> Rep Selector x
$cto :: forall x. Rep Selector x -> Selector
to :: forall x. Rep Selector x -> Selector
Generic, 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)
    deriving anyclass (Eq Selector
Eq Selector =>
(Int -> Selector -> Int) -> (Selector -> Int) -> Hashable Selector
Int -> Selector -> Int
Selector -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> Selector -> Int
hashWithSalt :: Int -> Selector -> Int
$chash :: Selector -> Int
hash :: Selector -> Int
Hashable)

toObject :: Selector -> Object
toObject :: Selector -> Object
toObject Selector
s =
    case Selector
s of
        ById Text
t -> Text -> Text -> Object
selector Text
"id" Text
t
        ByName Text
t -> Text -> Text -> Object
selector Text
"name" Text
t
        ByClass Text
t -> Text -> Text -> Object
selector Text
"class name" Text
t
        ByTag Text
t -> Text -> Text -> Object
selector Text
"tag name" Text
t
        ByLinkText Text
t -> Text -> Text -> Object
selector Text
"link text" Text
t
        ByPartialLinkText Text
t -> Text -> Text -> Object
selector Text
"partial link text" Text
t
        ByCSS Text
t -> Text -> Text -> Object
selector Text
"css selector" Text
t
        ByXPath Text
t -> Text -> Text -> Object
selector Text
"xpath" Text
t
        Anon Text
t -> Text -> Text -> Object
selector Text
"anon" Text
t
        AnonAttribute Text
t -> Text -> Text -> Object
selector Text
"anon attribute" Text
t
  where
    selector :: Text -> Text -> Object
    selector :: Text -> Text -> Object
selector Text
sn Text
t = [(Key, Value)] -> Object
forall v. [(Key, v)] -> KeyMap v
Object.fromList [Key
"using" Key -> Text -> (Key, Value)
forall v. ToJSON v => Key -> v -> (Key, Value)
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
sn, Key
"value" Key -> Text -> (Key, Value)
forall v. ToJSON v => Key -> v -> (Key, Value)
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
t]

instance ToJSON Selector where
    toJSON :: Selector -> Value
toJSON = Object -> Value
Object (Object -> Value) -> (Selector -> Object) -> Selector -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Selector -> Object
toObject

data SelectorFrom = SelectorFrom Element Selector

instance ToJSON SelectorFrom where
    toJSON :: SelectorFrom -> Value
toJSON (SelectorFrom Element{Text
elementId :: Text
elementId :: Element -> Text
..} Selector
s) = Object -> Value
Object (Object -> Value) -> Object -> Value
forall a b. (a -> b) -> a -> b
$ [(Key, Value)] -> Object
forall v. [(Key, v)] -> KeyMap v
Object.fromList [Key
"element" Key -> Text -> (Key, Value)
forall v. ToJSON v => Key -> v -> (Key, Value)
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
elementId] Object -> Object -> Object
forall a. Semigroup a => a -> a -> a
<> Selector -> Object
toObject Selector
s

data SelectorFromShadowRoot = SelectorFromShadowRoot Shadow Selector

instance ToJSON SelectorFromShadowRoot where
    toJSON :: SelectorFromShadowRoot -> Value
toJSON (SelectorFromShadowRoot Shadow{Text
shadowId :: Text
shadowId :: Shadow -> Text
..} Selector
s) = Object -> Value
Object (Object -> Value) -> Object -> Value
forall a b. (a -> b) -> a -> b
$ [(Key, Value)] -> Object
forall v. [(Key, v)] -> KeyMap v
Object.fromList [Key
"shadowRoot" Key -> Text -> (Key, Value)
forall v. ToJSON v => Key -> v -> (Key, Value)
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
shadowId] Object -> Object -> Object
forall a. Semigroup a => a -> a -> a
<> Selector -> Object
toObject Selector
s