Browse Source

Remove test suite and update

The test suite depends on hspec-webdriver, which appears to have issues and is not well
supported. Future plans for the site include using hakyll to generate json that will be
consumed by a frontend vuejs application. This will make selenium testing of the hakyll
become absolute (as well as generation of css using clay).

Signed-off-by: Collin J. Doering <>
Collin J. Doering 2 years ago
Signed by: rekahsoft <> GPG Key ID: 7B4DEB93212B3022
3 changed files with 11 additions and 171 deletions
  1. +11
  2. +0
  3. +0

+ 11
- 68 View File

@@ -1,15 +1,13 @@
# Source Code for **[#! Lambda Slang](**
# Source Code for **[#! Lambda Slang](**

* [Features](#features)
* [Tools](#tools)
* [License](#license)
* [Building](#building)
* [Running Tests](#running-tests)
* [Deploying](#deploying)
* [Issues](#issues)
* [Road Map](#road-map)

[#! Lambda Slang]( is the personal technical blog of *Collin Doering*,
[#! Lambda Slang]( is the personal technical blog of *Collin Doering*,
built using software that [respects our freedoms](

## Features <a name="features"></a>
@@ -27,7 +25,6 @@ The creation of this website was made possible by the following open source tool
* [Skeleton][] is used for CSS boilerplate
* [MathJax][] is used for rendering mathematics
* [Inkscape][] and the [Gimp][] were used to create various images/artwork
* [Selenium][] is used for automated testing using real browsers
* [Gnu Free Fonts][], specifically *FreeMono* is used as main font
* [Gnu Emacs][], because there is no place like home; and no greater editor!

@@ -45,27 +42,12 @@ question. Please see the LICENSE file for full details.

## Building <a name="building"></a>

All that is needed to build this site is cabal and a way to fetch required packages (whether
directly via the internet or by using the ```fetch``` argument to cabal).
[Stack][] is used to manage dependencies for this project. A simple wrapper script `site` is
provided that also takes care of building the static site and offering access to hakyll

$ cabal sandbox init # optional but recommended
$ cabal configure
$ cabal install --only-dependencies
$ cabal build
$ ./site build # build site
$ ./site server # view site at http://localhost:3000

## Running Tests <a name="running-tests"></a>

To the run the tests that accompany this site, one must have [Selenium][] installed and an
instances running on port 4444. Then one must run the following:

$ cabal configure --enable-tests
$ cabal install --enable-tests --only-dependencies
$ ./site test -s

The `-s` or `--run-selenium` option to `site test` starts a selenium server before running the
tests. Another way to run the tests is using cabal directly by running `cabal test`.
$ ./site build
$ ./site watch

## Deploying <a name="deploying"></a>

@@ -85,48 +67,9 @@ For example, this is how to deploy the production version of the site:

## Issues <a name="issues"></a>

Unfortunately, when trying to install the test-suite dependencies, `webdriver 0.6.1` fails to
install when using GHC 7.10 (*Jun 24, 2015*). This is due to a missing language pragma
`FlexibleContexts` in `src/Test/WebDriver/Commands.hs` (see
[bug ticket]( To get around this
problem you can download `webdriver` from hackage using `cabal get webdriver` and then fix the
problem yourself by adding the language pragma to the file `src/Test/WebDriver/Commands.hs`.
This issue has also been fixed upstream so you can use git to get the latest sources. Once the
working sources for `webdriver-0.6.1` are in place, run the following:

$ cd webdriver-0.6.1
$ cabal sandbox init
$ cabal configure
$ cabal install --only-dependencies
$ cabal build
$ cabal install
$ cd ..
$ cabal sandbox init --sandbox webdriver-0.6.1/.cabal-sandbox

This will share the cabal sandbox which we used to build and install our fixed version of
webdriver, with this project. Now the test-suite can be run once its dependencies are installed
(see [Running Tests](#running-tests)).

If you have an issue while browsing [my blog]( please file a bug using
my [flyspray powered bug tracker](

## Road Map <a name="road-map"></a>

There are still a few remaining rough edges to be fixed up. The ones I'm aware of are listed
below, if you find an issue please report it to me via email so I can make this site better.

* Include source files using some special syntax to avoid having to copy-paste source code into
articles. An example of what this could look like:

\`\`\` {.haskell .lineNumber include="files/source/SomeFile.hs"}

* Have a proper draft system instead of copying articles to and from `drafts` and `posts`.
* Use LocalStorage API to save previously visited articles so they can be viewed offline (and
saves on bandwidth). Note, this is already somewhat handled by the browsers cache, but the
cache can be unreliable and also can't be controlled from javascript so a better solution is
to use LocalStorage as mentioned.
* Make tag specific RSS feeds available via links (on individual tag pages and perhaps somewhere on the home page).
If you have an issue while browsing [my blog]( please file a issue
in the [blog-rekahsoft-ca]( issue

@@ -134,9 +77,9 @@ articles. An example of what this could look like:
[Gnu Emacs]:
[Gnu Free Fonts]:

+ 0
- 1
blog-rekahsoft-ca.cabal View File

@@ -98,18 +98,3 @@ executable gencss
-- Base language which the package is written in.
default-language: Haskell2010

+ 0
- 102
test/Main.hs View File

@@ -1,116 +0,0 @@

{-# LANGUAGE OverloadedStrings #-}
module Main where

import Control.Concurrent (threadDelay)
import Control.Exception (bracket)
import Control.Monad
import qualified Data.Text as T
import System.Process
import System.FilePath (takeExtension)
import System.Directory (getDirectoryContents, doesFileExist)
import Test.Hspec.WebDriver
import qualified Test.WebDriver.Commands.Wait as WDw
import qualified Test.WebDriver.Session as WDs

runSiteServerWith :: IO a -> IO ()
runSiteServerWith action = void $ bracket makeSiteProc terminateProcess (const action)
where makeSiteProc = do
let cp = shell "./site server"
cp' = cp { std_out = CreatePipe
, std_err = CreatePipe }
(_, _, _, ph) <- createProcess $ cp'

-- Pause for a moment to let http server start
threadDelay 250000

return ph

siteUrl :: String
siteUrl = "http://localhost:3000"

ensurePageLoaded :: WD ()
ensurePageLoaded = void $ WDw.waitUntil 10 $ findElem $ ById "page-content"

main :: IO ()
main = runSiteServerWith $ hspec $ do
describe "RekahSoft Blog Tests" $ do
-- session "for application cache" $ using [Firefox, Chrome] $ do
-- it "has a fresh cache manifest" $ do
-- pending

parallel $ session "general site navigation tests" $ using [chromeCaps] $ do
describe "navigation menuitems" $ do
context "when clicked" $ do
it "load the expected page and sets the menuitems parent as active" $ runWD $ do
openPage siteUrl
navItems <- findElems $ ByCSS "#nav a.menuitem"

flip mapM_ navItems $ \item -> do
itemHrefMaybe <- attr item "href"
itemHref <- case itemHrefMaybe of
Nothing -> fail "No href given on menuitem"
Just href -> return $ T.drop (length siteUrl) href

click item

activeItem <- findElem $ ByCSS $ "#nav > a.menuitem[href=\"" `T.append` itemHref `T.append` "\"]"
activeItem `shouldBeTag` "a"

describe "blog Page" $ do
it "is paginated" $ runWD $ do
openPage $ siteUrl ++ "/blog1.html"

pagination <- findElem $ ById "pagination"
noFirstPage <- findElemFrom pagination $ ByCSS "span.on-first-page"
noPreviousPage <- findElemFrom pagination $ ByCSS ""

pagination `shouldBeTag` "div"
noFirstPage `shouldBeTag` "span"
noPreviousPage `shouldBeTag` "span"

describe "loads all pages (html files in site root)" $ do
pages <- runIO $ filterDir "_site"

it "opens the app index page" $ runWD $ do
openPage siteUrl

flip mapM_ pages $ \page -> do
it ("opens the " ++ page ++ " page") $ runWD $ do
openPage $ siteUrl ++ "/" ++ page

describe "Loads all posts (html files in posts/*)" $ do
posts <- runIO $ filterDir "_site/posts"

flip mapM_ posts $ \post -> do
it ("opens post with filename " ++ post) $ runWD $ do
openPage $ siteUrl ++ "/posts/" ++ post

filterDir :: FilePath -> IO [FilePath]
filterDir fp = do
dirList <- getDirectoryContents fp
filterM (\x -> doesFileExist x >>= \y ->
return (y && takeExtension x == ".html")) dirList