kallisti-dev / hs-webdriver Goto Github PK
View Code? Open in Web Editor NEWA Haskell client for the Selenium WebDriver protocol.
Home Page: http://hackage.haskell.org/package/webdriver
License: BSD 3-Clause "New" or "Revised" License
A Haskell client for the Selenium WebDriver protocol.
Home Page: http://hackage.haskell.org/package/webdriver
License: BSD 3-Clause "New" or "Revised" License
The main page README has a link to an intermediate tutorial https://github.com/kallisti-dev/hs-webdriver/blob/master/examples/readme-example-intermediate.md which does not exist.
A feature request based on conversation with @adinapoli in issue #92
Currently all wait*
functions use explicit timeout parameters. Instead, include the ability to set a default timeout value as a state variable.
WDConfig
and WDSession
conf = defaultConfig
{ explicitWaitTimeout = Just 5 -- new config field. Nothing indicates indefinite waiting
}
main = runSession conf $ do
useWaitTimeout 10 -- can also set value via command instead of the config field
waitUntil foo
useIndefiniteWait -- remove timeout. indefinite waiting
waitUntil bar
waitWithTimeoutUntil 10 baz -- explicit timeout value provided. function name too wordy?
Nice and simple with no additional types to work with. Easy to use in situations where test cases are heavily decoupled. However, since the timeout state is "global" to the session it can easily leak into unrelated test cases. Feels like I'm working with an imperative language instead of Haskell, but then again this library is already heavily imperative in design due to the nature of the WebDriver framework.
WDWait
on top of WD
that keeps track of timeoutIn this variation, the wait*
combinators result in a WDWait a
instead of the current WD a
. This new WDWait
type is just a state monad on top of the existing WD
monad with a simple timeout value.
main = runSession defaultConfig $ do
withTimeout 10 $ do
waitUntil foo
waitUntil bar
withNoTimeout $ do -- no timeout. indefinite waiting
waitUntil baz
This results in an block-structured code flow, but might be clunky when test cases are heavily split up or when many different timeouts are desired. Feels more like I'm working with Haskell.
EDIT: On further consideration I don't necessarily think isolated test cases would be clunky. In fact it has a natural-language-esque presentation:
withTimeout 10 . waitUntil $ ...
or
withNoTimeout . waitUntil $ ...
Hi,
I just implemented code for making sure a new page has been loaded before returning from a wd
action. See here:
Would you accept a PR that provides waitForPageLoad
from Test.WebDriver.Commands.Wait
? (I would make ackStaleException
local, but do not insist either way; the *Sync
seem like too much clutter for a general-purpose webdriver library and I would leave them out.)
Any suggestions welcome.
What would be necessary? Anything to keep in mind?
If I decided to try and add this, would I be able to just model the Chrome module? Upon looking at the Chrome module, it looks like not much is in there.
Any direction is appreciated.
In commit b11eba5, the findElems
and findElemsFrom
functions no longer return lists of elements, but a single element. What is the motivation for this change, and is there another way to go about getting lists of elements off a page?
Filenames are lower case, and contents of examples/readme-example-beginner.lhs is just:
.\readme-example-beginner.md
It's a common task in testing large web applications with Selenium to inject Javascript code. However, the current mechanism for doing so is very low-level and could use big improvements.
Firstly, we want to support named arguments for javascript injection. To do that we change the JSArg
function to the following:
data JSArg = ToJSON a => JSArg Text a
The new Text
argument to the constructor is a variable name, and the variable will be automatically defined at the beginning of the script.
But we can also provide more advanced capabilities for large, complex scripts by implementing a state-writer monad. The idea is to change executeJS
and asyncJS
to the following type
(ToJavascript script, Foldable f, FromJSON result, WebDriver wd) =>f JSArg -> script -> wd a
with ToJavascript
being a class defined as:
class ToJavascript script where
addJSArg :: JSArg -> script -> script
getJavascript :: script -> Text
This class would have a Text
instance, allowing the new executeJS
to be mostly backwards compatible. However, now it is possible to define a WDJavascript
monad that implements a DSL for Javascript construction. An example of usage would be:
myScript :: Text -> Float -> HashMap String String -> [Int] -> WDJavascript ()
myScript arg1 arg2 arg3 arg4 = do
--declare two named variables
var "message" arg1
var "timer" arg2
--write raw JS
writeJS "console.log(message, timer);"
--retrieve all defined variables
varMap <- getVars
--delete the previous variables
deleteVar "message"
deleteVar "timer"
--define multiple variables as a assoc list
vars [("properties", JSArg arg3), ("vector", JSArg arg4)]
--delete multiple variables
deleteVars ["properties", "vector" -- delete multiple variables
This provides an easy framework for others to add Javascript injection facilities of their own. See https://github.com/zerobuzz/webtest/blob/84fed8a494872eeafb475eca6dcb79d43eb0cad0/src/Test/WebApp/WebDriver.hs for ideas on functions that could be implemented for AngularJS support etc.
I try to automate tests with the help of hs-webdriver, code see below. I have a selenium-server instance started ("Started SocketListener on 0.0.0.0:4444"). Everytime I run the main function in ghci I get an
*** Exception: TimeoutTriggered
and also the given page isn't opened. Do you have any idea what I'm doing wrong?
:set -XOverloadedStrings
:m + Test.WebDriver Control.Monad Test.WebDriver.Commands.Wait
let main :: IO() ; main = runSession defaultConfig $ do { openPage "http://stackoverflow.com/questions/ask" ; waitUntil 60 (findElem $ ByXPath ".//div") ; return () }
I also compiled the tests coming with the hs-webdriver now, but running .\dist\build\test-search-baidu\test-search-baidu.exe
got me a: test-search-baidu.exe: TimeoutTriggered.
I'm trying to port a python selenium webdriver script to haskell, but I'm having trouble with ByXPath
. I narrowed it down to this, which produces the huge StatusCodeException
below:
{-# LANGUAGE OverloadedStrings #-}
import Test.WebDriver
main :: IO ()
main = runSession chromeConfig $ do
openPage "http://google.com"
x <- findElem (ByXPath "div")
return ()
chromeConfig :: WDConfig
chromeConfig = defaultConfig { wdCapabilities = defaultCaps { browser = chrome }}
I'm using selenium-server-standalone-2.42.2.jar on Ubuntu 14.04. Other version info:
$ cabal info webdriver
...
Versions installed: 0.6.0.1
$ apt-cache policy ghc
ghc:
Installed: 7.6.3-10
$ /opt/google/chrome/google-chrome --version
Google Chrome 37.0.2062.94
This is the whole stderr from runghc xpathBug.hs
:
xpathBug.hs: StatusCodeException (Status {statusCode = 500, statusMessage = "Internal Server Error"}) [("Date","Wed, 03 Sep 2014 18:04:49 GMT"),("Server","Jetty/5.1.x (Linux/3.13.0-35-generic amd64 java/1.7.0_51"),("Expires","Thu, 01 Jan 1970 00:00:00 GMT"),("Cache-Control","no-cache"),("Content-Length","648602"),("Expires","Thu, 01 Jan 1970 00:00:00 GMT"),("Content-Type","application/json; charset=utf-8"),("Cache-Control","no-cache"),("X-Response-Body-Start","{\"status\":7,\"sessionId\":\"3d245a45-7553-4636-937d-de421c4b98cf\",\"value\":{\"message\":\"no such element\\n (Session info: chrome=37.0.2062.94)\\n (Driver info: chromedriver=2.9.248304,platform=Linux 3.13.0-35-generic x86_64) (WARNING: The server did not provide any stacktrace information)\\nCommand duration or timeout: 31 milliseconds\\nFor documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html\\nBuild info: version: '2.42.2', revision: '6a6995d', time: '2014-06-03 17:42:03'\\nSystem info: host: 'pav', ip: '127.0.1.1', os.name: 'Linux', os.arch: 'amd64', os.version: '3.13.0-35-generic', java.version: '1.7.0_51'\\nSession ID: b5a6550a1ac7c1a4ac81a95bccf276f3\\nDriver info: org.openqa.selenium.chrome.ChromeDriver\\nCapabilities [{platform=LINUX, acceptSslCerts=true, javascriptEnabled=true, browserName=chrome, chrome={userDataDir=/tmp/.com.google.Chrome.aj2IMR}, rotatable=false, locationContextEnabled=true, version=37.0.2062.94, takesHeapSnapshot=true, cssSelectorsEnabled=true, databaseEnabled=false, handlesAlerts=true, browserConnectionEnabled=false, nativeEvents=true, webStorageEnabled=true, applicationCacheEnabled=false, takesScreenshot=true}]\",\"screen\":\"iVBORw0KGgoAAAANSUhEUgAABpAAAAQaCAIAAADL9awBAACAAElEQVR42uy9B1hUV7f4zXfv99zv\\ne+978yaxoYg1FpQqvdfp7Uw7M3OmVxg6SBNUVFDsYO+994YKiqiIDQUpsSEqiYkFY2yJbxJj4n/N\\nHMRR0AyiYu7/7Of37Gfttdde6+w9ZzZzFufM2MgwLgHBp4BExKFSQtxHONnb97K3793XVPrZ97az\\n793LzXU4lRwsRtnEKnUWcimvvciwNpXEYhIQEBAQEBAQEBAQEBB8QBA25S2aD9f7+NFDqG3eV5FK\\nEAICnNwJY6qqKoHKyrPAmTMVp06dPHHieHn5saNHjxw5XPqXlB4qyRk/ur1x4YSWYrzhw4f0tusV\\nEUHKyhq9fPnKPYX79+wtWrpsZdaYcRQq3c7ObvCgARKR2Zh4sV4Fk3CVKkyMoahY8JeAGRi/w2v0\\ndujUMIk4lEIOApmH0KTi0InZ/JhIUkR4gKUZ8WIREBAQEBAQEBAQEBAQfGgQNqWlbq35QL2PHz0E\\n4b0l7DAxh4AAZ+6cgsePH6enpyeby8gXJdmiJL0oiS9KwouSkpLy448/gpN2BZVhXDaL0r9/3/CI\\niO3bd1xpuPb4518f/vzs7oPfb937/fa9p00//nrh0vX1G3dQacz+/fqymGS5lEe8WJYoldjCRfNv\\n3fr+/v17fwmYgbFCIWlXiNf2PjHKprmPCHF3pdPCKKRghENdtCChvnq8Sh4IXbHRzAtnx546nHq8\\nJAUTB7+SWyReLwICAgICAgICAgICAoKPBcKmfLTex48eQv3eEnYSEZuAAGfunIKffvqJSqVyOBwu\\nl8s3Fx6PBzJoWCwWnU6HXhKJFBYWFhwcHBgY6Ofn5+3t7eHh4e7uHhIScu/ePXBifUSpBGEyyIO+\\nGpSXN/nBg0c///v3B4+ffXfn3xVV14oPVxcerC492Vhx/qdzl39puPHLNzcfT5k+Z+BXg8ikUBhI\\nvF4tiDH01q3v7/14t+nubRNNt+6YuPkqt0APvffu3QVjGNKuEJZ7kIBHF3h6nJbLs/z9tm8ZPW0i\\nz9/X89aN9V9XjNHIA8kRgVcvz6k4kn6yNLV4V1xosLvlWOLFIiAgICAgIHjvzCmY3NhQ18Ksmbl/\\nuylMTxPvnJe8e/5InG1LcqsqK69fv75r8+oWJbB5mraDgcLD/DsFPPqWJzWdQifO/VkT0inRn0fZ\\nWK78J8XJ8uJr9bXvDAwnNr3/S1Cr0JKiHQAI7R2LsClv0Xy43sePHkL93hJ2IiGLgABnzuz8n376\\niUajcblcgUCAmotQKOTz+aABIScnZ9q0aQaDITw8PCQkJDAw0N/f38fHx9PT093dPTg4+O7du+DE\\nynBilM1kkL/6atDGjZse//TkpyfPfnjw+60fni5ZuSUknNZ/wOD+A4eQaIJZi/eWVPxUfOrnsuon\\nF679tGzVliFDhlEpYTDcykCzqBEtzEN5S6INy1OTlo9KfRvpI5fGRC7AUMuxn1qsFlCx4P79eytX\\nL7/34w8/3Lt77fqVH+41Aa2Eu1caLt1pug3GMKRdIWC1cdgsitbX57RSeQBFJ7DDHzQtO1ac7Obq\\neOXitDNl6aQw96QEyc3rS04dTisvSTGo/CPCAlvGWvmSdcoaEhAQEBAQEPx9qT13vLGhrvrssZrK\\nchCg/hBR4JPMuLGpbX6eeUuXleSni8s35R1ePQZnxpSc/eayaeOGJTNGg6bUzI65iR2cRViIX6eA\\nR++shF0nzv1ZE9Ip0Z9H2Viu/DuwYO504EO8lU4eO9ihhN2xg/87Nq6c8RmZGYnEBv4WNCox/m8Y\\nEN5hOMKmtNStNR+o9/GjhyC8t4QdKmC+BZUcnTJpzLLFs4DJk8Yq5cK3238QUPnE1Ru3T1dLPn7o\\n/8vmiCfsqFQqn88XCoVisRjDMKhBlslkp06dKikp2bZtW1VVVU5OTmhoaFBQkGXCLjAw8M6dO+DE\\nynAilNOvX5+8vMmPHz95/MT8DOwPT3ftK/f08h8y1FmsiOGi2r79h7p5BC/ZeG7n0cebSx7tOfZT\\nTf2jvGlz+/XtA8OtDHTF17eF7wSCh9nZv6xc+du2bb/t2dM2O3b8umbNowkTbspklmM/tVgveZGw\\nu3b9ypu4eq3+0uXzFy7WAnjCrl0h8G2IQQtPDgq6YDCkSrj5U2QMh6/Onxm7f0dsgL9XejI1LZEU\\nERaYOpLzfcO0o0VJY9Np0V5ujKFDWAzSy9ziJ7uGBAQEBAQEBH9P5FI+fkU3YVx6TnYGLu/ZuWH3\\njvXrVi2SSwXvJYpGLS49sAs8Qw2ylV3WMzNdVLYh99CKzBIzUzIjx6focVbPSCp5od8+O76DEwkN\\n9u0U8OidlbDrxLk/a0I6JfrzKBvLlW8vSxbm428lEN77e/bksQMdS9gd+N+xd41KjZ8xbUJstIbY\\nxi0TUPsLt0RHKUGWiDgqJYqfhyBAE5TRRhUYtDcxhbApH6338aOHUA8"),("X-Request-URL","POST http://127.0.0.1:4444/wd/hub/session/3d245a45-7553-4636-937d-de421c4b98cf/element")] (CJ {expose = []})
Hi,
the phantomjs driver works fine with HTTP, but fails to load sites with HTTPS.
Even with 'acceptSSLCerts = Just True' they don't load.
here is my code:
myConfig :: WDConfig
myConfig = defaultConfig { wdCapabilities = defaultCaps { browser = Browser "phantomjs",
acceptSSLCerts = Just True
]} }
printing out the WD getSource:
"<html><head></head><body></body></html>"
printing out the WD getCurrentURL (for all HTTPS pages):
"about:blank"
BTW I am running pahntomjs 1.9.8, stack lts 3.16, webdriver-0.6.3.1
Any idea how to fix it?
thanks,
Alex.
Hi, this is more of a question rather than a issue. I think if runSession
creates a WDSession
, it doesn't need one as argument. Or how was I wrong?
A skunkworks implementation of mine, because I couldn't figure out how to extract it otherwise:
runSession' :: WDConfig -> WD a -> IO WDSession
runSession' conf test = do
ref <- (newIORef undefined)
runSession conf (dumpSessionHistoryWithIORef ref test)
s <- readIORef ref
return s
dumpSessionHistoryWithIORef :: WDSessionStateControl wd => IORef WDSession -> wd a -> wd a
dumpSessionHistoryWithIORef ref = (`finally` (getSession >>= writeIORef ref))
Example use:
> runSession' remoteConfig test >>= print . wdSessHist
Required capabilities need to be added to hs-webdriver. I've added some experimental code regarding this in the vinyl-capabilities branch that can be used as a reference. I'm still unsure if I want to use vinyl in release code.
I intended to use waitWhile
to wait for the absence of an element and was puzzled that the code did not work. My understanding is that waitWhile
should retry as long as the command succeeds. However, the following implementation seems to call retry
if the command wd
fails. Am I missing something obvious?
-- |Like 'waitUntil'', but retries the action until it either fails or
-- until the timeout is exceeded.
waitWhile' :: SessionState m => Int -> Double -> m a -> m ()
waitWhile' = wait' handler
where
handler retry wd = do
b <- (wd >> return Nothing) `catches` [Handler handleFailedCommand
,Handler handleExpectFailed
]
maybe (return ()) retry b
where
handleFailedCommand e@(FailedCommand NoSuchElement _) = return (Just $ show e)
handleFailedCommand err = throwIO err
handleExpectFailed (e :: ExpectFailed) = return (Just $ show e)
The line
main = runSession config $ do
should be
main = runSession myConfig $ do
given your declaration
I've seen this warning when building the library: Literal 405 is out of the Word8 range 0..255
. I believe 405 is an HTTP status code. Is it possible to be in the JSON body as well?
I imagine it is common to want to do IO in WD for troubleshooting or logging. I found these useful (especially before I found the session's browser window, which hides in the back on OSX):
p :: Show a => a -> WD ()
p = liftIO . print
printUrl :: WD ()
printUrl = getCurrentURL >>= liftIO . putStrLn
writeScreenshot :: FilePath -> WD ()
writeScreenshot f = screenshot >>= liftIO . B.writeFile f
wait :: Int -> WD ()
wait = liftIO . threadDelay
But I wonder if it would be possible to have IO actions just work in WD.
Environment: Windows 7, webdriver-0.5.1, ghc-7.6, firefox 23.0.1
When I use selenium-server-standalone-2.33.0.jar all is ok.
Prelude> :m Test.WebDriver
Prelude Test.WebDriver> runWD defaultSession $ createSession allCaps
...
Loading package zip-archive-0.1.3.4 ... linking ... done.
Loading package webdriver-0.5.1 ... linking ... done.
WDSession {wdHost = "127.0.0.1", wdPort = 4444, wdBasePath = "/wd/hub", wdSessId = Just (SessionId "ac4cc864-63f1-42a1-8
67a-98e723271d75")}
Prelude Test.WebDriver>
When I use selenium-server-standalone-2.35.0.jar I have problems:
Prelude Test.WebDriver> runWD defaultSession $ createSession allCaps
*** Exception: BadJSON "when expecting a Text, encountered Object instead"
Prelude Test.WebDriver>
Log of selenium-server doesn't contain errors and firefox starts successfully
C:\selenium>java -jar c:\selenium\selenium-server-standalone-2.35.0.jar
рту 22, 2013 1:37:28 PM org.openqa.grid.selenium.GridLauncher main
INFO: Launching a standalone server
13:37:28.303 INFO - Java: Oracle Corporation 23.7-b01
13:37:28.304 INFO - OS: Windows 7 6.1 amd64
13:37:28.312 INFO - v2.35.0, with Core v2.35.0. Built from revision c916b9d
13:37:28.396 INFO - RemoteWebDriver instances should connect to: http://127.0.0.
1:4444/wd/hub
13:37:28.397 INFO - Version Jetty/5.1.x
13:37:28.397 INFO - Started HttpContext[/selenium-server/driver,/selenium-server
/driver]
13:37:28.398 INFO - Started HttpContext[/selenium-server,/selenium-server]
13:37:28.398 INFO - Started HttpContext[/,/]
13:37:28.432 INFO - Started org.openqa.jetty.jetty.servlet.ServletHandler@5bb79d
4f
13:37:28.433 INFO - Started HttpContext[/wd,/wd]
13:37:28.442 INFO - Started SocketListener on 0.0.0.0:4444
13:37:28.442 INFO - Started org.openqa.jetty.jetty.Server@7f08d052
13:38:09.818 INFO - Executing: [new session: {platform=ANY, javascriptEnabled=tr
ue, acceptSslCerts=true, firefox_binary=null, browserName=firefox, rotatable=tru
e, locationContextEnabled=true, version=null, loggingPrefs=org.openqa.selenium.l
ogging.L..., firefox_profile=null, databaseEnabled=true, cssSelectorsEnabled=tru
e, handlesAlerts=true, browserConnectionEnabled=true, proxy={proxyType=SYSTEM},
webStorageEnabled=true, nativeEvents=true, applicationCacheEnabled=true, takesSc
reenshot=true}] at URL: /session)
13:38:09.828 INFO - Creating a new session for Capabilities [{platform=ANY, java
scriptEnabled=true, acceptSslCerts=true, firefox_binary=null, browserName=firefo
x, rotatable=true, locationContextEnabled=true, version=null, loggingPrefs=org.o
penqa.selenium.logging.LoggingPreferences@5613e573, firefox_profile=null, databa
seEnabled=true, cssSelectorsEnabled=true, handlesAlerts=true, browserConnectionE
nabled=true, nativeEvents=true, webStorageEnabled=true, proxy={proxyType=SYSTEM}
, applicationCacheEnabled=true, takesScreenshot=true}]
13:38:17.788 INFO - Done: /session
I think it would be good to have a better read me file. For example it could be included (for beginners like me) how to use the tool (first you have to start selenium webdriver standalone server with java -jar, then you can start your Haskell program). The list of compatible selenium versions would be also important.
src/Test/WebDriver/Internal.hs:52:56:
Couldn't match expected type `Maybe b0' with actual type `URI'
In the second argument of `($)', namely
`relURI `relativeTo` baseURI'
In the expression: return . fromJust $ relURI `relativeTo` baseURI
In a case alternative:
(Just baseURI, Just relURI)
-> return . fromJust $ relURI `relativeTo` baseURI
Now relativeTo
returns URI
instead of Maybe URI
(http://hackage.haskell.org/packages/archive/network/2.4.0.1/doc/html/Network-URI.html#v:relativeTo).
TL;DR: The fixes have not been released to Hackage yet. Please read the last comment and release the latest fixes on master to Hackage so that people don't continue running into this problem. Read my last comment for more info.
In cabal I have specified ==0.6.* of this library.
I have written the following condition code which I have passed to a waitUntil:
containsText "Installed and ready to go!" =<< findElem (ById "upm-plugin-status-dialog")
containsText :: (WebDriver wd) => String -> Element -> wd ()
containsText text element = do
actualText <- getText element
expect (text `isInfixOf` T.unpack actualText)
And when it runs I get the following back from selenium server:
12:32:10.974 INFO - Executing: [find element: By.id: upm-plugin-status-dialog])
12:32:11.741 WARN - Exception thrown
org.openqa.selenium.NoSuchElementException: no such element
(Session info: chrome=38.0.2125.111)
(Driver info: chromedriver=2.11.298611 (d1120fdf51badec2f7b63a96e19a58d4783de84d),platform=Mac OS X 10.9.5 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 42 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.43.1', revision: '5163bce', time: '2014-09-10 16:27:33'
System info: host: 'Roberts-Mac-Pro.local', ip: '192.168.1.150', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.9.5', java.version: '1.7.0_60'
Session ID: 20877f4da18a7aef7a9817985b873274
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{platform=MAC, acceptSslCerts=true, javascriptEnabled=true, browserName=chrome, chrome={userDataDir=/var/folders/zs/16ql7n3j5bs7vb0h2bbycz080000gp/T/.org.chromium.Chromium.lsl41L}, rotatable=false, locationContextEnabled=true, mobileEmulationEnabled=false, version=38.0.2125.111, takesHeapSnapshot=true, cssSelectorsEnabled=true, databaseEnabled=false, handlesAlerts=true, browserConnectionEnabled=false, nativeEvents=true, webStorageEnabled=true, applicationCacheEnabled=false, takesScreenshot=true}]
at sun.reflect.GeneratedConstructorAccessor20.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:204)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:156)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:599)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:352)
at org.openqa.selenium.remote.RemoteWebDriver.findElementById(RemoteWebDriver.java:393)
at org.openqa.selenium.By$ById.findElement(By.java:214)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:344)
at sun.reflect.GeneratedMethodAccessor22.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.openqa.selenium.support.events.EventFiringWebDriver$2.invoke(EventFiringWebDriver.java:101)
at com.sun.proxy.$Proxy1.findElement(Unknown Source)
at org.openqa.selenium.support.events.EventFiringWebDriver.findElement(EventFiringWebDriver.java:184)
at org.openqa.selenium.remote.server.handler.FindElement.call(FindElement.java:47)
at org.openqa.selenium.remote.server.handler.FindElement.call(FindElement.java:1)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at org.openqa.selenium.remote.server.DefaultSession$1.run(DefaultSession.java:169)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
12:32:11.742 WARN - Exception: no such element
(Session info: chrome=38.0.2125.111)
(Driver info: chromedriver=2.11.298611 (d1120fdf51badec2f7b63a96e19a58d4783de84d),platform=Mac OS X 10.9.5 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 42 milliseconds
Now, as far as I can tell that looks like a standard not found exception to me which the documentation of waitUntil (and the code itself) seems to suggest that it will catch. However, it is not until I replace that condition with:
expect . not . null =<< findElems (ById "upm-plugin-status-dialog")
that the code works as expected. What is going on here and how can I make this work all of the time? I think that this may be a bug.
P.S. Oh, and on the haskell side I am getting this:
remind-me-integration: StatusCodeException (Status {statusCode = 500, statusMessage = "Internal Server Error"}) [("Date","Sun, 09 Nov 2014 01:32:10 GMT"),("Server","Jetty/5.1.x (Mac OS X/10.9.5 x86_64 java/1.7.0_60"),("Expires","Thu, 01 Jan 1970 00:00:00 GMT"),("Cache-Control","no-cache"),("Content-Length","467018"),("Expires","Thu, 01 Jan 1970 00:00:00 GMT"),("Content-Type","application/json; charset=utf-8"),("Cache-Control","no-cache"),("X-Response-Body-Start","{\"status\":7,\"sessionId\":\"6890a609-3c81-4234-8f7d-11555d06983d\",\"value\":{\"message\":\"no such element\\n (Session info: chrome=38.0.2125.111)\\n (Driver info: chromedriver=2.11.298611 (d1120fdf51badec2f7b63a96e19a58d4783de84d),platform=Mac OS X 10.9.5 x86_64) (WARNING: The server did not provide any stacktrace information)\\nCommand duration or timeout: 42 milliseconds\\nFor documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html\\nBuild info: version: '2.43.1', revision: '5163bce', time: '2014-09-10 16:27:33'\\nSystem info: host: 'Roberts-Mac-Pro.local', ip: '192.168.1.150', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.9.5', java.version: '1.7.0_60'\\nSession ID: 20877f4da18a7aef7a9817985b873274\\nDriver info: org.openqa.selenium.chrome.ChromeDriver\\nCapabilities [{platform=MAC, acceptSslCerts=true, javascriptEnabled=true, browserName=chrome, chrome={userDataDir=/var/folders/zs/16ql7n3j5bs7vb0h2bbycz080000gp/T/.org.chromium.Chromium.lsl41L}, rotatable=false, locationContextEnabled=true, mobileEmulationEnabled=false, version=38.0.2125.111, takesHeapSnapshot=true, cssSelectorsEnabled=true, databaseEnabled=false, handlesAlerts=true, browserConnectionEnabled=false, nativeEvents=true, webStorageEnabled=true, applicationCacheEnabled=false, takesScreenshot=true}]\",\"screen\":\"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\\n6xzyWmajnUP"),("X-Request-URL","POST http://127.0.0.1:4444/wd/hub/session/6890a609-3c81-4234-8f7d-11555d06983d/element")] (CJ {expose = []})
[ 3 of 13] Compiling Test.WebDriver.Firefox.Profile ( src\Test\WebDriver\Firefox
\Profile.hs, dist\build\Test\WebDriver\Firefox\Profile.o )
src\Test\WebDriver\Firefox\Profile.hs:196:3:
Warning: A do-notation statement discarded a result of type SBS.ByteString.
Suppress this warning by saying "_ <- ($)
padSpaces string "user_pref
("",
or by using the flag -fno-warn-unused-do-bind
src\Test\WebDriver\Firefox\Profile.hs:198:3:
Warning: A do-notation statement discarded a result of type Char.
Suppress this warning by saying "_ <- ($) padSpaces char ','",
or by using the flag -fno-warn-unused-do-bind
src\Test\WebDriver\Firefox\Profile.hs:200:3:
Warning: A do-notation statement discarded a result of type SBS.ByteString.
Suppress this warning by saying "_ <- ($) padSpaces string ");"",
or by using the flag -fno-warn-unused-do-bind
Unpacking to webdriver-0.6.1/
Resolving dependencies...
Configuring webdriver-0.6.1...
Building webdriver-0.6.1...
Preprocessing library webdriver-0.6.1...
[ 1 of 17] Compiling Test.WebDriver.Chrome.Extension ( src/Test/WebDriver/Chrome/Extension.hs, dist/build/Test/WebDriver/Chrome/Extension.o )
src/Test/WebDriver/Chrome/Extension.hs:13:1: Warning:
The import of ‘Control.Applicative’ is redundant
except perhaps to import instances from ‘Control.Applicative’
To import instances alone, use: import Control.Applicative()
[ 2 of 17] Compiling Test.WebDriver.Common.Profile ( src/Test/WebDriver/Common/Profile.hs, dist/build/Test/WebDriver/Common/Profile.o )
src/Test/WebDriver/Common/Profile.hs:54:1: Warning:
The import of ‘Control.Applicative’ is redundant
except perhaps to import instances from ‘Control.Applicative’
To import instances alone, use: import Control.Applicative()
[ 3 of 17] Compiling Test.WebDriver.Firefox.Profile ( src/Test/WebDriver/Firefox/Profile.hs, dist/build/Test/WebDriver/Firefox/Profile.o )
src/Test/WebDriver/Firefox/Profile.hs:32:1: Warning:
Module ‘Data.Attoparsec.Char8’ is deprecated:
This module will be removed in the next major release.
[ 4 of 17] Compiling Test.WebDriver.Utils ( src/Test/WebDriver/Utils.hs, dist/build/Test/WebDriver/Utils.o )
[ 5 of 17] Compiling Test.WebDriver.JSON ( src/Test/WebDriver/JSON.hs, dist/build/Test/WebDriver/JSON.o )
src/Test/WebDriver/JSON.hs:41:1: Warning:
The import of ‘Control.Applicative’ is redundant
except perhaps to import instances from ‘Control.Applicative’
To import instances alone, use: import Control.Applicative()
[ 6 of 17] Compiling Test.WebDriver.Capabilities ( src/Test/WebDriver/Capabilities.hs, dist/build/Test/WebDriver/Capabilities.o )
src/Test/WebDriver/Capabilities.hs:19:1: Warning:
The import of ‘Control.Applicative’ is redundant
except perhaps to import instances from ‘Control.Applicative’
To import instances alone, use: import Control.Applicative()
[ 7 of 17] Compiling Test.WebDriver.Session ( src/Test/WebDriver/Session.hs, dist/build/Test/WebDriver/Session.o )
src/Test/WebDriver/Session.hs:21:1: Warning:
Module ‘Control.Monad.Error’ is deprecated:
Use Control.Monad.Except instead
src/Test/WebDriver/Session.hs:23:1: Warning:
The import of ‘Control.Monad.Writer.Strict’ is redundant
except perhaps to import instances from ‘Control.Monad.Writer.Strict’
To import instances alone, use: import Control.Monad.Writer.Strict()
src/Test/WebDriver/Session.hs:104:11: Warning:
In the use of type constructor or class ‘Error’
(imported from Control.Monad.Error, but defined in Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"
src/Test/WebDriver/Session.hs:104:57: Warning:
In the use of type constructor or class ‘ErrorT’
(imported from Control.Monad.Error, but defined in Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"
[ 8 of 17] Compiling Test.WebDriver.Config ( src/Test/WebDriver/Config.hs, dist/build/Test/WebDriver/Config.o )
[ 9 of 17] Compiling Test.WebDriver.Class ( src/Test/WebDriver/Class.hs, dist/build/Test/WebDriver/Class.o )
src/Test/WebDriver/Class.hs:19:1: Warning:
Module ‘Control.Monad.Error’ is deprecated:
Use Control.Monad.Except instead
src/Test/WebDriver/Class.hs:21:1: Warning:
The import of ‘Control.Monad.Writer.Strict’ is redundant
except perhaps to import instances from ‘Control.Monad.Writer.Strict’
To import instances alone, use: import Control.Monad.Writer.Strict()
src/Test/WebDriver/Class.hs:68:11: Warning:
In the use of type constructor or class ‘Error’
(imported from Control.Monad.Error, but defined in Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"
src/Test/WebDriver/Class.hs:68:48: Warning:
In the use of type constructor or class ‘ErrorT’
(imported from Control.Monad.Error, but defined in Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"
[10 of 17] Compiling Test.WebDriver.Internal ( src/Test/WebDriver/Internal.hs, dist/build/Test/WebDriver/Internal.o )
src/Test/WebDriver/Internal.hs:39:1: Warning:
The import of ‘Control.Applicative’ is redundant
except perhaps to import instances from ‘Control.Applicative’
To import instances alone, use: import Control.Applicative()
src/Test/WebDriver/Internal.hs:46:1: Warning:
The import of ‘Word’ from module ‘Data.Word’ is redundant
[11 of 17] Compiling Test.WebDriver.Commands.Internal ( src/Test/WebDriver/Commands/Internal.hs, dist/build/Test/WebDriver/Commands/Internal.o )
src/Test/WebDriver/Commands/Internal.hs:30:1: Warning:
The import of ‘Control.Applicative’ is redundant
except perhaps to import instances from ‘Control.Applicative’
To import instances alone, use: import Control.Applicative()
[12 of 17] Compiling Test.WebDriver.Exceptions ( src/Test/WebDriver/Exceptions.hs, dist/build/Test/WebDriver/Exceptions.o )
[13 of 17] Compiling Test.WebDriver.Commands.Wait ( src/Test/WebDriver/Commands/Wait.hs, dist/build/Test/WebDriver/Commands/Wait.o )
[14 of 17] Compiling Test.WebDriver.Commands ( src/Test/WebDriver/Commands.hs, dist/build/Test/WebDriver/Commands.o )
src/Test/WebDriver/Commands.hs:221:15:
Could not deduce (L.Exception e0) arising from a use of ‘handle’
from the context (WebDriver wd, FromJSON a)
bound by the type signature for
asyncJS :: (WebDriver wd, FromJSON a) =>
[JSArg] -> Text -> wd (Maybe a)
at src/Test/WebDriver/Commands.hs:220:12-72
The type variable ‘e0’ is ambiguous
Note: there are several potential instances:
instance L.Exception L.NestedAtomically
-- Defined in ‘Control.Exception.Base’
instance L.Exception L.NoMethodError
-- Defined in ‘Control.Exception.Base’
instance L.Exception L.NonTermination
-- Defined in ‘Control.Exception.Base’
...plus 31 others
In the expression: handle timeout
In the expression:
handle timeout $ Just <$> (fromJSON' =<< getResult)
In an equation for ‘asyncJS’:
asyncJS a s
= handle timeout $ Just <$> (fromJSON' =<< getResult)
where
getResult
= doSessCommand methodPost "/execute_async"
. pair ("args", "script")
$ (a, s)
timeout (FailedCommand Timeout _) = return Nothing
timeout (FailedCommand ScriptTimeout _) = return Nothing
timeout err = throwIO err
src/Test/WebDriver/Commands.hs:225:5:
Non type-variable argument in the constraint: MonadBase IO m
(Use FlexibleContexts to permit this)
When checking that ‘timeout’ has the inferred type
timeout :: forall (m :: * -> *) a.
MonadBase IO m =>
FailedCommand -> m (Maybe a)
In an equation for ‘asyncJS’:
asyncJS a s
= handle timeout $ Just <$> (fromJSON' =<< getResult)
where
getResult
= doSessCommand methodPost "/execute_async"
. pair ("args", "script")
$ (a, s)
timeout (FailedCommand Timeout _) = return Nothing
timeout (FailedCommand ScriptTimeout _) = return Nothing
timeout err = throwIO err
Hi again!
I try to use a proxy capability. When I use Manual
proxy setting - it works like a charm: I see corresponding proxy settings in the Network settings of the Firefox (started by Selenium standalone server). But when I try to use PAC
proxy, I got a problem.
This is my code:
capabilities :: Capabilities
capabilities = defaultCaps { proxy = pacBasedProxy }
where
pacBasedProxy = PAC { autoConfigUrl = pathToBrowserPACFileAsURL }
Function pathToBrowserPACFileAsURL
returns a file path to the PAC-file (like file:///tmp/selenium-pac-test
). File actually exists, its content is correct (I've checked it). But if I look in the Network setting of the Firefox - I see an empty path to the PAC-file:
As you can see, PAC proxy option is active, but path to the PAC-file is empty... Obviuosly, PAC-based proxy doesn't work in this case...
This is what I see in the Selenium server's log:
Executing: [new session: Capabilities [{proxy={autoConfigUrl=file:///tmp/selenium-pac-test, proxyType=PAC}, loggingPrefs=org.openqa.selenium.logging.LoggingPreferences@27d3164b, browserName=firefox, platform=ANY}]])
Selenium see that I want to use PAC-based proxy, but why is path to the PAC-file empty? How can I fix it?
Not sure it's duplicated or not. When I try to install the library in Docker haskell ( https://hub.docker.com/_/haskell/ ) with command
cabal update; cabal install webdriver;
I got the error message:
src/Test/WebDriver/Internal.hs:16:82: error:
Module
‘Network.HTTP.Client’
does not export
‘HttpException(ResponseTimeout)’
cabal: Leaving directory '/tmp/cabal-tmp-59/webdriver-0.8.3'
cabal: Error: some packages failed to install:
webdriver-0.8.3 failed during the building phase. The exception was:
ExitFailure 1
When install with stack, It installed successfully (not sure about run)
Compiling with stackage LTS (which uses aeson 0.8 still) results in the compile error
src/Test/WebDriver/Commands.hs:216:55:
Could not deduce (ToJSON (f JSArg)) arising from a use of ‘pair’
from the context (Foldable f, FromJSON a, WebDriver wd)
bound by the type signature for
executeJS :: (Foldable f, FromJSON a, WebDriver wd) =>
f JSArg -> Text -> wd a
at src/Test/WebDriver/Commands.hs:213:14-78
In the second argument of ‘(.)’, namely ‘pair ("args", "script")’
In the expression:
doSessCommand methodPost "/execute" . pair ("args", "script")
In the expression:
doSessCommand methodPost "/execute" . pair ("args", "script")
$ (a, s)
src/Test/WebDriver/Commands.hs:228:61:
Could not deduce (ToJSON (f JSArg)) arising from a use of ‘pair’
from the context (Foldable f, FromJSON a, WebDriver wd)
bound by the type signature for
asyncJS :: (Foldable f, FromJSON a, WebDriver wd) =>
f JSArg -> Text -> wd (Maybe a)
at src/Test/WebDriver/Commands.hs:225:12-84
In the second argument of ‘(.)’, namely ‘pair ("args", "script")’
In the expression:
doSessCommand methodPost "/execute_async" . pair ("args", "script")
In the expression:
doSessCommand methodPost "/execute_async" . pair ("args", "script")
$ (a, s)
Doing some investigation, it looks like the instance (Foldable f, ToJSON a) => ToJSON (f a)
was only added in aeson version 0.10. The simplest fix is just to call toList
explicitly. If I changed executeJs
and asyncJs
to call toList
on the parameter a
, everything compiles.
The following code snippet fails at runtime with "*** Exception: connect: does not exist (Connection refused)"
import Test.WebDriver
main :: IO ()
main = runSession defaultSession defaultCaps $ do
openPage "http://www.wikipedia.org/"
I have a couple packages I want to release that depend on git head of this package.
There are some commands in Selenium 3 that are currently not implemented in hs-webdriver.
Consider the following test file (using my base path pull request):
{-# LANGUAGE OverloadedStrings #-}
import Test.WebDriver
main :: IO ()
main = runSession session caps testWD
where
session = defaultSession { wdPort = 9515
, wdBasePath = "" }
caps = defaultCaps { browser = chrome }
testWD :: WD ()
testWD = do
openPage "http://www.google.com/"
searchBox <- findElem (ByName "q")
sendKeys "yesodweb" searchBox
submit searchBox
What I get is
$ runhaskell webdriver.hs
webdriver.hs: HTTPStatusUnknown (3,0,3) "See Other "
However, a Chrome window is opened and using Wireshark I see that chromedriver did return a new session ID:
POST /session HTTP/1.1
Connection: close
User-Agent: haskell-HTTP/4000.2.3
Host: 127.0.0.1:9515
Accept: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
Content-Length: 451
{"desiredCapabilities":{"handlesAlerts":null,"chrome.switches":[],"takesScreenshot":null,"locationContextEnabled":null,"javascriptEnabled":null,"rotatable":null,"cssSelectorsEnabled":null,"databaseEnabled":null,"applicationCacheEnabled":null,"proxy":{"proxyType":"SYSTEM"},"webStorageEnabled":null,"browserConnectionEnabled":null,"acceptSslCerts":null,"platform":"ANY","nativeEvents":null,"browserName":"chrome","version":null,"chrome.extensions":[]}}
HTTP/1.1 303 See Other
connection:close
content-type:application/json; charset=utf-8
location:/session/5a09d158240152c716198fb75b290c9b
content-length:66
{"status":303,"value":"/session/5a09d158240152c716198fb75b290c9b"}
Am I doing something wrong? How do you use Chrome with webdriver
?
https://github.com/kallisti-dev/hs-webdriver/blob/master/examples/readme-example-beginner.md#hello-world shouldn't the example for google here evaluate sendKeys "Hello, World!" searchInput
before submit searchInput
?
C:\Documents and Settings*>cabal install webdriver
Resolving dependencies...
Configuring network-2.4.1.0...
cabal: The package has a './configure' script. This requires a Unix compatibility toolchain such as MinGW+MSYS or Cygwin.
Configuring unix-2.6.0.1...
cabal: The package has a './configure' script. This requires a Unix compatibility toolchain such as MinGW+MSYS or Cygwin.
Why does it need unix
package on Windows at all?
It would be nice to add the trivial instance ToPref
for the data ProfilePref
, so you can use ProfilePref
constructors with the addPref
function.
Compatability was broken with #96. Avoid using CPP if possible.
webdriver has problems compiling against versions of http-client >= 0.5.0. It gives the following error:
src\Test\WebDriver\Internal.hs:16:82: error:
Module
`Network.HTTP.Client'
does not export
`HttpException(ResponseTimeout)'
It seems the latest versions of http-client made changes to the HttpException datatype.
I get some errors All elements are sent over enclosed in curly brackets {} ie. {uuidnumber} and must be transmitted back the same way in the url. Using percent encoding seemed to work for this.
moveToFrom and moveToCenter, maximize all seem to fail.
Also Is there any interest in using Either for error handling rather than err. I think this would make more since for Haskell.
with the following config
myConfig = defaultConfig { wdCapabilities = defaultCaps { browser = Browser "phantomjs",
acceptSSLCerts = Just True,
additionalCaps = [("phantomjs.page.settings.userAgent","...")
,("phantomjs.cli.args", "--webdriver-logfile=/tmp/foo.log --webdriver=11122 --ignore-ssl-errors=yes")
,("phantomjs.binary.path", "/usr/local/bin/phantomjs")
]} }
the selenium node does not pass the cli args to the phantomjs process:
12:12:03.125 INFO - Executing: [new session: Capabilities [{proxy={proxyType=SYSTEM}, acceptSslCerts=true, phantomjs.binary.path=/usr/local/bin/phantomjs, phant
omjs.page.settings.userAgent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:42.0) Gecko/20100101 Firefox/42.0, browserName=phantomjs, phantomjs.cli.args=--webd
river-logfile=/tmp/foo.log --webdriver=11122 --ignore-ssl-errors=yes, platform=ANY}]])
12:12:03.169 INFO - Creating a new session for Capabilities [{proxy={proxyType=SYSTEM}, acceptSslCerts=true, phantomjs.binary.path=/usr/local/bin/phantomjs, phantomjs.page.settings.userAgent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:42.0) Gecko/20100101 Firefox/42.0, browserName=phantomjs, phantomjs.cli.args=--webdriver-logfile=/tmp/foo.log --webdriver=11122 --ignore-ssl-errors=yes, platform=ANY}]
12:12:03.182 INFO - executable: /usr/local/bin/phantomjs
12:12:03.182 INFO - port: 38882
12:12:03.182 INFO - arguments: [--proxy-type=system, --webdriver=38882, --webdriver-logfile=/var/crawler/selenium/phantomjsdriver.log]
12:12:03.182 INFO - environment: {}
PhantomJS is launching GhostDriver...
[INFO - 2015-12-08T11:12:03.864Z] GhostDriver - Main - running on port 38882
[INFO - 2015-12-08T11:12:04.038Z] Session [82d711a0-9d9c-11e5-9a25-558c16c15c60] - page.settings - {"XSSAuditingEnabled":false,"javascriptCanCloseWindows":true
,"javascriptCanOpenWindows":true,"javascriptEnabled":true,"loadImages":true,"localToRemoteUrlAccessEnabled":false,"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.
as can be seen in the line "12:12:03.182 INFO - arguments: " the arguments are not the ones from the haskell code.
I am using sleenium node with 'selenium-server-standalone.2.48.2.jar' and phantomjs 1.9.8,
and starting the node like this:
$JAVA -jar ./selenium-server-standalone.jar \
-role node \
-hub http://localhost:4444/grid/register \
-host localhost \
-port $PORT \
-browser "browserName=phantomjs,maxInstances=5" \
-maxSession 5 \
-timeout 30000 \
-nodePolling 5000 \
-downPollingLimit 3 \
-unregisterIfStillDownAfter 5000
Any Ideas how to pass command line args to the phantomjs browser?
Do I miss something?
thanks,
Alex.
It looks like this is already on master, but not released to Hackage. Could you make this release available?
I have the following definitions:
backspace, enter, escape :: Text
(backspace, enter, escape) = ("\xE003", "\xE007", "\xE00C")
shift, control, alt, command :: Text
(shift, control, alt, command) = ("\xE008", "\xE009", "\xE00A", "\xE03D")
...
It'd be useful to have a .Keys
module (designed to be imported qualified) providing said definitions, to allow something like this:
sendKeys ("Some category" <> K.enter) =<< select ".add-category"
I can think of several alternatives to this:
enter_
and then there'd be no need for qualified importssendKeys'
function handling input of the form foo{enter}bar{shift}
(or something like that)If you want, I will make a pull request.
(Also, the link in the description of sendKeys
is broken.)
Currently network >= 2.4 && < 2.6 is required.
Is it possible to bump the version to >2.6 (and maybe add network-url as advised by the network maintainers)?
This would make building darcsden easier for me.
ByteString
instances of FromJSON
and ToJSON
classes were removed in aeson-0.7.0.0 (haskell/aeson#126).
Resolving dependencies...
Configuring webdriver-0.5.3...
Building webdriver-0.5.3...
Preprocessing library webdriver-0.5.3...
[ 1 of 15] Compiling Test.WebDriver.Chrome.Extension ( src/Test/WebDriver/Chrome/Extension.hs, dist/dist-sandbox-983400fd/build/Test/WebDriver/Chrome/Extension.o )
src/Test/WebDriver/Chrome/Extension.hs:17:51:
No instance for (ToJSON ByteString)
arising from the 'deriving' clause of a data type declaration
Possible fix:
add an instance declaration for (ToJSON ByteString)
or use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (ToJSON ChromeExtension)
src/Test/WebDriver/Chrome/Extension.hs:17:59:
No instance for (FromJSON ByteString)
arising from the 'deriving' clause of a data type declaration
Possible fix:
add an instance declaration for (FromJSON ByteString)
or use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (FromJSON ChromeExtension)
Failed to install webdriver-0.5.3
Selenium 3 is out. I haven't been able to verify that hs-webdriver supports it due to time constraints, but I would like to make sure it does. Last I checked there was a major overhaul of the Rest API in the works.
Hi!
I need to click some button, but not with a click
function, but with a native JS. I see a special function for this task, executeJS
. So this is my code:
...
button <- findElement . ById $ "clearCart"
info <- elemInfo button
executeJS [JSArg info] "arguments[0].click();"
...
But I got a runtime error:
BadJSON "when expecting a (), encountered Null instead"
How can I fix it?
Thanks for this great, super useful lib. (Aside: I found it much easier than the equivalent ruby or javascript libs. I did have quite a bit of trouble getting selenium working on osx. brew install selenium-server-standalone worked in the end, though it doesn't understand some things like getLogs. selenium-server-standalone245 opened the browser only. Other hurdles: getting a new enough java; finding the selenium browser window, which is backgrounded on OSX; discovering the wait* commands in the API and learning when they are needed, eg between openPage and findElem; "element detached from DOM" errors when trying to combine findElems.)
On to my question: it would be really helpful to be able to run exploratory commands one at a time in GHCI and observe the effects, keeping the session open. Is this possible ? I thought I had found a way:
*Main> :t runSession defaultConfig $ createSession def
runSession defaultConfig $ createSession def
:: IO Test.WebDriver.Session.WDSession
..but this happens:
*Main> s <- runSession defaultConfig $ createSession def
*** Exception: ServerError "Server response session ID (Just (SessionId \"6fabed28-712d-4b48-bb45-88b5f5bf3b5f\")) does not match local session ID (Just (SessionId \"2dc93519-bcab-4588-9bce-18e4dfc82b1f\"))"
I posted this on issue on Stackoverflow (see link below) because I'm not sure if the issue is with your code or with the selenium server. I was hoping there was a way to communicate with Firefox directly.
http://stackoverflow.com/questions/24960534/how-do-i-get-webdriver-working-on-a-mac-from-haskell
on the page
https://github.com/kallisti-dev/hs-webdriver
at the bottom the following link is broken:
...(see #Documentation).
https://github.com/kallisti-dev/hs-webdriver/blob/master/Documentation
thanks,
Alex
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.