Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add newWindow endpoint #30

Merged
merged 6 commits into from
Mar 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -283,6 +284,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