Skip to content

Commit

Permalink
Add newWindow endpoint (#30)
Browse files Browse the repository at this point in the history
See https://w3c.github.io/webdriver/#new-window.

Partially addresses #28.

Co-authored-by: nbloomf <[email protected]>
  • Loading branch information
nbloomf and nbloomf authored Mar 27, 2021
1 parent 3c4982a commit ac3f7c4
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 1 deletion.
20 changes: 20 additions & 0 deletions src/Web/Api/WebDriver/Endpoints.hs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ module Web.Api.WebDriver.Endpoints (
, switchToWindow
-- ** Get Window Handles
, getWindowHandles
-- ** New Window
, newWindow
-- ** Switch To Frame
, switchToFrame
-- ** Switch To Parent Frame
Expand Down Expand Up @@ -519,6 +521,24 @@ getWindowHandles = do
>>= (return . map (ContextId . unpack))


-- | See <https://w3c.github.io/webdriver/webdriver-spec.html#new-window>
newWindow
:: (Monad eff, Monad (t eff), MonadTrans t)
=> ContextType -> WebDriverTT t eff (ContextId, ContextType)
newWindow ctxTypeReq = do
baseUrl <- theRemoteUrlWithSession
let !payload = encode $ object [ "type" .= ctxTypeReq ]
response <- httpPost (baseUrl ++ "/window/new") payload
>>= (return . _responseBody)
>>= parseJson
>>= lookupKeyJson "value"
ctxId <- lookupKeyJson "handle" response
>>= constructFromJson
ctxType <- lookupKeyJson "type" response
>>= constructFromJson
return (ctxId, ctxType)


-- | See <https://w3c.github.io/webdriver/webdriver-spec.html#switch-to-frame>.
switchToFrame
:: (Monad eff, Monad (t eff), MonadTrans t)
Expand Down
34 changes: 34 additions & 0 deletions src/Web/Api/WebDriver/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module Web.Api.WebDriver.Types (
SessionId
, ElementRef(..)
, ContextId(..)
, ContextType(..)
, Selector
, AttributeName
, PropertyName
Expand Down Expand Up @@ -145,6 +146,39 @@ instance Show ContextId where
instance IsString ContextId where
fromString = ContextId

instance FromJSON ContextId where
parseJSON (String x) = return $ ContextId $ unpack x
parseJSON invalid = typeMismatch "ContextType" invalid

instance ToJSON ContextId where
toJSON (ContextId x) = String $ pack x

instance Arbitrary ContextId where
arbitrary = ContextId <$> arbitrary

-- | Type of a /top level browsing context/; see <https://html.spec.whatwg.org/#top-level-browsing-context>.
data ContextType = WindowContext | TabContext
deriving (Eq, Enum, Bounded)

instance Show ContextType where
show t = case t of
WindowContext -> "window"
TabContext -> "tab"

instance FromJSON ContextType where
parseJSON (String x) = case x of
"window" -> return WindowContext
"tab" -> return TabContext
_ -> unrecognizedValue "ContextType" x
parseJSON invalid = typeMismatch "ContextType" invalid

instance ToJSON ContextType where
toJSON WindowContext = String "window"
toJSON TabContext = String "tab"

instance Arbitrary ContextType where
arbitrary = arbitraryBoundedEnum

-- | For use with a /Locator Strategy/. See <https://w3c.github.io/webdriver/webdriver-spec.html#locator-strategies>.
type Selector = String

Expand Down
23 changes: 23 additions & 0 deletions test/Web/Api/WebDriver/Monad/Test/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ defaultWebDriverServer = MockWorld
[_,"session",session_id,"window"] ->
post_session_id_window session_id payload

{- New Window -}
[_,"session",session_id,"window","new"] ->
post_session_id_window_new session_id payload

{- Switch To Frame -}
[_,"session",session_id,"frame"] ->
post_session_id_frame session_id payload
Expand Down Expand Up @@ -453,6 +457,25 @@ post_session_id_window session_id payload = do
return _success_with_empty_object


{- New Window -}

post_session_id_window_new
:: String
-> LB.ByteString
-> MockNetwork WebDriverServerState HttpResponse
post_session_id_window_new session_id payload = do
verifyIsActiveSession session_id
st <- getMockServer
case _load_page "about:blank" st of -- not actually switching contexts here
Nothing -> errorMockNetwork _err_unknown_error
Just _st -> do
modifyMockServer (const _st)
return $ _success_with_value $ object
[ ( "handle", String "handle-id" )
, ( "type", String "tab" )
]


{- Get Window Handles -}

get_session_id_window_handles
Expand Down
7 changes: 7 additions & 0 deletions test/Web/Api/WebDriver/Monad/Test/Server/Page.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module Web.Api.WebDriver.Monad.Test.Server.Page (
, cssMatchDocument
, parseCss
, tagIsClearable
, pageAboutBlank
) where

import Text.ParserCombinators.Parsec
Expand Down Expand Up @@ -79,6 +80,12 @@ node tag attrs children =
let elementId = "" in
Document{..}

pageAboutBlank :: Page
pageAboutBlank = Page
{ contents = Text ""
, url = "about:blank"
}


assignIds :: String -> Document -> Document
assignIds _ h@(Text str) = Text str
Expand Down
4 changes: 3 additions & 1 deletion test/Web/Api/WebDriver/Monad/Test/Server/State.hs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ _load_page path st = do
then return _success_page
else if file == "invalidElementState.html"
then return _invalidElementState_page
else requestPage path (_internets st)
else if file == "about:blank"
then return pageAboutBlank
else requestPage path (_internets st)
return $ st
{ _current_page = p
, _history = (_current_page st) : _history st
Expand Down
18 changes: 18 additions & 0 deletions test/Web/Api/WebDriver/Monad/Test/Session/Success.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ successfulExit buildTestCase dir =
, buildTestCase "getWindowHandle" (_test_getWindowHandle_success)
, buildTestCase "switchToWindow" (_test_switchToWindow_success)
, buildTestCase "getWindowHandles" (_test_getWindowHandles_success path)
, buildTestCase "newWindow" (_test_newWindow_success path)
, buildTestCase "switchToFrame" (_test_switchToFrame_success path)
, buildTestCase "switchToParentFrame" (_test_switchToParentFrame_success path)
, buildTestCase "getWindowRect" (_test_getWindowRect_success)
Expand Down Expand Up @@ -272,6 +273,23 @@ _test_getWindowHandles_success page =



_test_newWindow_success
:: (Monad eff) => FilePath -> WebDriverT eff ()
_test_newWindow_success page =
let
session = do
navigateTo page
(handle, _) <- newWindow TabContext
switchToWindow handle
url <- getCurrentUrl
assertEqual url "about:blank" "default url"
assertSuccess "yay"
return ()

in catchError session unexpectedError



_test_switchToFrame_success
:: (Monad eff) => FilePath -> WebDriverT eff ()
_test_switchToFrame_success page =
Expand Down
6 changes: 6 additions & 0 deletions test/Web/Api/WebDriver/Types/Test.hs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ test_fromJson_toJson_id = testGroup "fromJSON . toJSON == id"

, QC.testProperty "(ResponseErrorCode) fromJSON . toJSON == id" $
(prop_fromJson_toJson_id :: ResponseErrorCode -> Bool)

, QC.testProperty "(ContextId) fromJSON . toJSON == id" $
(prop_fromJson_toJson_id :: ContextId -> Bool)

, QC.testProperty "(ContextType) fromJSON . toJSON == id" $
(prop_fromJson_toJson_id :: ContextType -> Bool)
]


Expand Down

0 comments on commit ac3f7c4

Please sign in to comment.