Simply, create the exact version of byLabel

This commit is contained in:
pythonissam 2017-11-26 07:22:25 +00:00
parent cab78b65c2
commit 80aa45cf18
2 changed files with 80 additions and 0 deletions

View File

@ -73,6 +73,7 @@ module Yesod.Test
-- These functions let you add parameters to your request based -- These functions let you add parameters to your request based
-- on currently displayed label names. -- on currently displayed label names.
, byLabel , byLabel
, byLabelExact
, fileByLabel , fileByLabel
-- *** CSRF Tokens -- *** CSRF Tokens
@ -563,6 +564,46 @@ nameFromLabel label = do
name:_ -> return name name:_ -> return name
_ -> failure $ "More than one label contained " <> label _ -> failure $ "More than one label contained " <> label
-- This looks up the name of a field based on the contents of the label pointing to it (exact).
nameFromLabelExact :: T.Text -> RequestBuilder site T.Text
nameFromLabelExact label = do
mres <- fmap rbdResponse ST.get
res <-
case mres of
Nothing -> failure "nameFromLabel: No response available"
Just res -> return res
let
body = simpleBody res
mlabel = parseHTML body
$// C.element "label"
>=> contentIs label
mfor = mlabel >>= attribute "for"
contentIs x c
| x == T.concat (c $// content) = [c]
| otherwise = []
case mfor of
for:[] -> do
let mname = parseHTML body
$// attributeIs "id" for
>=> attribute "name"
case mname of
"":_ -> failure $ T.concat
[ "Label "
, label
, " resolved to id "
, for
, " which was not found. "
]
name:_ -> return name
[] -> failure $ "No input with id " <> for
[] ->
case filter (/= "") $ mlabel >>= (child >=> C.element "input" >=> attribute "name") of
[] -> failure $ "No label contained: " <> label
name:_ -> return name
_ -> failure $ "More than one label contained " <> label
(<>) :: T.Text -> T.Text -> T.Text (<>) :: T.Text -> T.Text -> T.Text
(<>) = T.append (<>) = T.append
@ -598,6 +639,38 @@ byLabel label value = do
name <- nameFromLabel label name <- nameFromLabel label
addPostParam name value addPostParam name value
-- How does this work for the alternate <label><input></label> syntax?
-- | Finds the @\<label>@ with the given value, finds its corresponding @\<input>@, then adds a parameter
-- for that input to the request body.
--
-- ==== __Examples__
--
-- Given this HTML, we want to submit @f1=Michael@ to the server:
--
-- > <form method="POST">
-- > <label for="user">Username</label>
-- > <input id="user" name="f1" />
-- > </form>
--
-- You can set this parameter like so:
--
-- > request $ do
-- > byLabel "Username" "Michael"
--
-- This function also supports the implicit label syntax, in which
-- the @\<input>@ is nested inside the @\<label>@ rather than specified with @for@:
--
-- > <form method="POST">
-- > <label>Username <input name="f1"> </label>
-- > </form>
byLabelExact :: T.Text -- ^ The text contained in the @\<label>@.
-> T.Text -- ^ The value to set the parameter to.
-> RequestBuilder site ()
byLabelExact label value = do
name <- nameFromLabelExact label
addPostParam name value
-- | Finds the @\<label>@ with the given value, finds its corresponding @\<input>@, then adds a file for that input to the request body. -- | Finds the @\<label>@ with the given value, finds its corresponding @\<input>@, then adds a file for that input to the request body.
-- --
-- ==== __Examples__ -- ==== __Examples__

View File

@ -223,6 +223,13 @@ main = hspec $ do
setUrl ("labels2" :: Text) setUrl ("labels2" :: Text)
byLabel "hobby" "fishing") byLabel "hobby" "fishing")
assertEq "failure wasn't called" (isLeft bad) True assertEq "failure wasn't called" (isLeft bad) True
yit "byLabelExact performs an exact match over the given label name" $ do
get ("/labels2" :: Text)
(bad :: Either SomeException ()) <- try (request $ do
setMethod "POST"
setUrl ("labels2" :: Text)
byLabelExact "hobby" "fishing")
assertEq "failure was called" (isRight bad) True
ydescribe "Content-Type handling" $ do ydescribe "Content-Type handling" $ do
yit "can set a content-type" $ do yit "can set a content-type" $ do