webdriver 0.8.0.3 → 0.8.0.4
raw patch · 7 files changed
+28/−146 lines, 7 filesdep −webdriverdep ~basedep ~textPVP ok
version bump matches the API change (PVP)
Dependencies removed: webdriver
Dependency ranges changed: base, text
API changes (from Hackage documentation)
Files
- .ghci +2/−2
- CHANGELOG.md +4/−0
- README.md +3/−63
- src/Test/WebDriver/Commands.hs +5/−1
- src/Test/WebDriver/Exceptions/Internal.hs +2/−2
- test/search-baidu.hs +0/−50
- webdriver.cabal +12/−28
.ghci view
@@ -1,2 +1,2 @@-:set -XOverloadedStrings-:m Test.WebDriver Data.Default+:set -XOverloadedStrings -XScopedTypeVariables+:m Test.WebDriver Data.Default.Class
CHANGELOG.md view
@@ -1,7 +1,11 @@ #Change Log +##0.8.0.4+* Quick fix to parse "unsupported command" errors when using Marionette driver (Selenium + Marionette has nonstandard behavior when reporting that error type)+ ##0.8.0.3 * Fixed build errors for GHC < 7.10. webdriver now builds with GHC stable releases 7.4.2, 7.6.3, and 7.8.4+* Fixed support for bytestring 0.9.* ##0.8.0.2 * Fixed issue introduced in 0.8 that caused build failure when using aeson < 0.10
README.md view
@@ -55,6 +55,7 @@ #Getting Started+ WebDriver is a client-server protocol. Since hs-webdriver only implements a WebDriver client, you must have a WebDriver server to which you can connect in order to make use of this library. ##Using the Selenium Server@@ -65,71 +66,10 @@ The server should now be listening at localhost on port 4444. ##Hello, World!-With the Selenium server running locally, you're ready to write browser automation scripts in Haskell. Let's start with a simple example.-```hs- {-# LANGUAGE OverloadedStrings #-}- import Test.WebDriver- - myConfig :: WDConfig- myConfig = defaultConfig- - main :: IO ()- main = runSession myConfig $ do- openPage "http://google.com"- searchInput <- findElem (ByCSS "input[type='text']")- sendKeys "Hello, World!" searchInput-```-hs-webdriver uses a very simple EDSL implemented within a state monad. Interacting with the remote browser is done via a sequence of commands within this monad. The state monad maintains implicit information about the WebDriver session between commands, so that individual commands only need to specify parameters relevant to the action they perform. If you're new to monads, there are plenty of resources available for learning on the web, but for now you can think of the `WD` monad as implementing a very simple imperative language operating on an implicit browser session.--Let's take a closer look at each piece of this example.--###Demonic invocations: a bit of boilerplate-```hs- {-# LANGUAGE OverloadedStrings #-}-```-hs-webdriver uses the `Text` type to represent Unicode character sequences, which is significantly more efficient than the standard Haskell structure for strings. This directive tells GHC to overload string literals so that they can be used to represent `Text` values (or, more generally, any other instance of [IsString](http://hackage.haskell.org/package/base-4.7.0.2/docs/Data-String.html])).-```hs- import Test.WebDriver-```-This line is fairly straightforward; we need to import the library so that we can use it! Most of the basic API is available through the `Test.WebDriver` module, so this is the only import you should need for most tests. There are other modules that may be of interest for advanced usage; in particular, `Test.WebDriver.Commands.Wait` provides so-called "implicit waits" as defined by other WebDriver libraries. There are also modules that support custom Firefox and Chrome extensions, but these features are not fully stable.--###Configuring a WebDriver session-```hs- myConfig :: WDConfig- myConfig = defaultConfig-```-To configure a new WebDriver session, we use the `WDConfig` type; this is a record type with various configuration fields. To connect to the Selenium server that we spawned earlier, the `defaultConfig` is sufficient. By default, the browser is set to Firefox, but that can be changed; the following configuration will use Google Chrome instead of Firefox for our test:-```hs- myConfig :: WDConfig- myConfig = defaultConfig { wdCapabilities = defaultCaps { browser = chrome } }-```-*Note*: To use Google Chrome, you need to install Google's proprietary [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/) in a directory where it can be recognized by Selenium Server (see: https://code.google.com/p/selenium/wiki/ChromeDriver).- -###Initializing tests-```hs- main :: IO ()- main = runSession myConfig $ do-```-`main` is the standard entry point for a Haskell program, defined as a value of type `IO a`. In order to transform our `WD` action into an `IO` action, we use the `runSession` function, which has the type:-```hs- runSession :: WDConfig -> WD a -> IO a- ```-So we pass to `runSession` our configuration record along with a WebDriver "script" to perform, and it transforms the script into a side-effectful `IO` action. The `WDConfig` record is used to automatically initialize our session with the remote server.--*Note*: `runSession` does not automatically close the session it creates. This is intentional, as you may want to manually inspect the browser state after your code executes. If you want to have the session automatically close, you can use the `finallyClose` function to provide this behavior.-```hs- main = runSession myConfig . finallyClose $ do-```+With the Selenium server running locally, you're ready to write browser automation scripts in Haskell. -###Actually writing tests!-```hs- openPage "http://google.com"- searchInput <- findElem (ByCSS "input[type='text']")- sendKeys "Hello, World!" searchInput-```-Interaction with the browser is accomplished via WebDriver "commands", which are just function calls within the `WD` monad. Most of these commands are defined in the `Test.WebDriver.Commands` modules, and are fairly self-explanatory. In this example, `openPage` opens a new URL, and `findElem` searches for a DOM element on the current page which matches the given selector (possible selectors include `ById`, `ByName`, `ByClass`, `ByTag`, `ByLinkText`, `ByCSS`, and `ByXPath`). The DOM Element found by the result of the search is bound to the local variable `searchInput`, and `sendKeys` sends a sequence of emulated keystrokes to the given element.+A [simple example can be found here](/examples/readme-example-beginner.md), written in literate Haskell so that you can compile it with GHC yourself. It is very beginner friendly and assumes no prior knowledge of Haskell. If you already have an intermediate understanding of Haskell, [this is the example for you](/examples/readme-example-intermediate.md) For other examples see the [examples](examples/) and [test/etc](test/etc/) directory. -This example contains all of the basic elements of a simple WebDriver test. For complete documentation on each command, check out the documentation for [Test.WebDriver.Commands](https://hackage.haskell.org/package/webdriver-0.6.0.4/docs/Test-WebDriver-Commands.html) #Integration with Haskell Testing Frameworks
src/Test/WebDriver/Commands.hs view
@@ -290,7 +290,11 @@ -- |Closes the given window closeWindow :: WebDriver wd => WindowHandle -> wd ()-closeWindow = noReturn . doSessCommand methodDelete "/window" . single "name"+closeWindow w = do+ cw <- getCurrentWindow+ focusWindow w+ noReturn $ doSessCommand methodDelete "/window" Null+ unless (w == cw) $ focusWindow cw -- |Maximizes the current window if not already maximized maximize :: WebDriver wd => wd ()
src/Test/WebDriver/Exceptions/Internal.hs view
@@ -20,7 +20,7 @@ import Control.Applicative import Data.Typeable (Typeable)-import Data.Maybe (fromMaybe)+import Data.Maybe (fromMaybe, catMaybes) import Data.Word import Prelude -- hides some "unused import" warnings@@ -162,7 +162,7 @@ <*> pure Nothing <*> (fmap TLE.encodeUtf8 <$> opt "screen" Nothing) <*> opt "class" Nothing- <*> opt "stackTrace" []+ <*> (catMaybes <$> opt "stackTrace" []) where req :: FromJSON a => Text -> Parser a req = (o .:) --required key opt :: FromJSON a => Text -> a -> Parser a
− test/search-baidu.hs
@@ -1,50 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-module Main where--import Control.Monad-import Control.Applicative-import Data.List-import qualified Data.Text as T-import Test.WebDriver-import Test.WebDriver.Commands.Wait--import Prelude--chromeConf = useBrowser chrome defaultConfig-ffConf = defaultConfig---- Have no fun with baidu but only cause it is loading fast than google in China.----baidu :: WD ()-baidu = do - openPage "http://www.baidu.com/"- waitUntil 15 $- expect . (== "http://www.baidu.com/") =<< getCurrentURL--searchBaidu :: WD ()-searchBaidu = do- searchBox <- findElem (ById "kw")- sendKeys "Cheese!" searchBox- submit searchBox- waitUntil 15 $ do- title <- getTitle- expect ("Cheese!" `T.isInfixOf` title)-- container <- findElem (ById "container")- eList1 <- findElems (ByCSS "c-container")- eList2 <- findElems (ByClass "c-container")- expect =<< (fmap and $ zipWithM (<==>) eList1 eList2)-- forM_ eList1 $ \e -> findElemsFrom e (ByTag "a")----testCase c = void . runSession c . finallyClose $ (baidu >> searchBaidu)--testSuites = mapM_ testCase [ffConf, chromeConf]--main = do- --testCase capsChrome `seq` testCase capsFF- --mapM_ (forkOS . testCase) [capsFF, capsChrome]- testSuites- print "done"
webdriver.cabal view
@@ -1,17 +1,17 @@ Name: webdriver-Version: 0.8.0.3-Cabal-Version: >= 1.8+Version: 0.8.0.4+Cabal-Version: >= 1.10 License: BSD3 License-File: LICENSE Author: Adam Curtis Maintainer: kallisti.dev@gmail.com Homepage: https://github.com/kallisti-dev/hs-webdriver-Bug-reports: https://github.com/kallisti-dev/hs-webdriver/issues-Category: Web, Browser, Testing+Bug-Reports: https://github.com/kallisti-dev/hs-webdriver/issues+Category: Web, Browser, Testing, WebDriver, Selenium Synopsis: a Haskell client for the Selenium WebDriver protocol-Build-type: Simple-Extra-source-files: README.md, TODO.md, CHANGELOG.md, .ghci-Tested-with: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.2 +Build-Type: Simple+Extra-Source-Files: README.md, TODO.md, CHANGELOG.md, .ghci+Tested-With: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.2 Description: A Selenium WebDriver client for Haskell. You can use it to automate browser sessions@@ -24,21 +24,22 @@ see the change log at <https://github.com/kallisti-dev/hs-webdriver/blob/master/CHANGELOG.md> -source-repository head+Source-Repository head type: git location: git://github.com/kallisti-dev/hs-webdriver.git -flag network-uri+Flag network-uri description: Get Network.URI from the network-uri package default: True -flag developer+Flag developer description: Package development mode default: False manual: True -library+Library hs-source-dirs: src+ default-language: Haskell2010 ghc-options: -Wall if flag(developer) cpp-options: -DCABAL_BUILD_DEVELOPER@@ -91,20 +92,3 @@ other-modules: Test.WebDriver.Internal Test.WebDriver.Exceptions.Internal--Test-Suite search-baidu- type: exitcode-stdio-1.0- main-is: test/search-baidu.hs- ghc-options: -threaded- build-depends: base,- webdriver,- text----Test-Suite all-tests--- type: detailed-0.9--- test-module: all-tests.hs--- extensions: OverloadedStrings--- ghc-options: -Wall -threaded--- build-depends: base,--- webdriver,--- hspec