diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,4 @@
-Copyright Luke Lau (c) 2018
-
+Copyright Luke Lau 2018-2020.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -35,13 +35,13 @@
 ```
 
 Try out the example tests in the `example` directory with `cabal test`.
-For more examples check the [Wiki](https://github.com/bubba/lsp-test/wiki/Introduction).
+For more examples check the [Wiki](https://github.com/bubba/lsp-test/wiki/Introduction), or see this [introductory blog post](https://lukelau.me/haskell/posts/lsp-test/).
 
 Whilst writing your tests you may want to debug them to see what's going wrong.
 You can set the `logMessages` and `logStdErr` options in `SessionConfig` to see what the server is up to.
 There are also corresponding environment variables so you can turn them on from the command line:
 ```
-LSP_TEST_LOG_MESSAGES=1 cabal test
+LSP_TEST_LOG_MESSAGES=1 LSP_TEST_LOG_STDERR=1 cabal test
 ```
 
 ## Developing
diff --git a/lsp-test.cabal b/lsp-test.cabal
--- a/lsp-test.cabal
+++ b/lsp-test.cabal
@@ -1,5 +1,5 @@
 name:                lsp-test
-version:             0.11.0.1
+version:             0.11.0.2
 synopsis:            Functional test framework for LSP servers.
 description:
   A test framework for writing tests against
@@ -22,7 +22,7 @@
 cabal-version:       2.0
 extra-source-files:  README.md
                    , ChangeLog.md
-tested-with:         GHC == 8.2.2 , GHC == 8.4.2 , GHC == 8.4.3, GHC == 8.6.4, GHC == 8.6.5, GHC == 8.8.1, GHC == 8.10.1
+tested-with:         GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.3, GHC == 8.10.1
 
 source-repository head
   type:     git
@@ -55,7 +55,7 @@
                      , Diff
                      , directory
                      , filepath
-                     , Glob ^>= 0.10
+                     , Glob >= 0.9 && < 0.11
                      , lens
                      , mtl
                      , parser-combinators >= 1.2
diff --git a/src/Language/Haskell/LSP/Test.hs b/src/Language/Haskell/LSP/Test.hs
--- a/src/Language/Haskell/LSP/Test.hs
+++ b/src/Language/Haskell/LSP/Test.hs
@@ -604,16 +604,19 @@
   let params = TextDocumentPositionParams doc pos Nothing
   rsp <- request TextDocumentDefinition params :: Session DefinitionResponse
   case getResponseResult rsp of
-      SingleLoc loc -> pure [loc]
-      MultiLoc locs -> pure locs
+    SingleLoc loc -> pure [loc]
+    MultiLoc locs -> pure locs
 
 -- | Returns the type definition(s) for the term at the specified position.
 getTypeDefinitions :: TextDocumentIdentifier -- ^ The document the term is in.
-               -> Position -- ^ The position the term is at.
-               -> Session [Location] -- ^ The location(s) of the definitions
-getTypeDefinitions doc pos =
+                   -> Position -- ^ The position the term is at.
+                   -> Session [Location] -- ^ The location(s) of the definitions
+getTypeDefinitions doc pos = do
   let params = TextDocumentPositionParams doc pos Nothing
-  in getResponseResult <$> request TextDocumentTypeDefinition params
+  rsp <- request TextDocumentTypeDefinition params :: Session TypeDefinitionResponse
+  case getResponseResult rsp of
+    SingleLoc loc -> pure [loc]
+    MultiLoc locs -> pure locs
 
 -- | Renames the term at the specified position.
 rename :: TextDocumentIdentifier -> Position -> String -> Session ()
diff --git a/src/Language/Haskell/LSP/Test/Replay.hs b/src/Language/Haskell/LSP/Test/Replay.hs
--- a/src/Language/Haskell/LSP/Test/Replay.hs
+++ b/src/Language/Haskell/LSP/Test/Replay.hs
@@ -34,6 +34,8 @@
 -- makes sure it matches up with an expected response.
 -- The session directory should have a captured session file in it
 -- named "session.log".
+-- You can get these capture files from 'Language.Haskell.LSP.resCaptureFile' in
+-- haskell-lsp.
 replaySession :: String -- ^ The command to run the server.
               -> FilePath -- ^ The recorded session directory.
               -> IO ()
diff --git a/src/Language/Haskell/LSP/Test/Session.hs b/src/Language/Haskell/LSP/Test/Session.hs
--- a/src/Language/Haskell/LSP/Test/Session.hs
+++ b/src/Language/Haskell/LSP/Test/Session.hs
@@ -71,7 +71,7 @@
 import System.Console.ANSI
 import System.Directory
 import System.IO
-import System.Process (ProcessHandle())
+import System.Process (waitForProcess, ProcessHandle())
 import System.Timeout
 
 -- | A session representing one instance of launching and connecting to a server.
@@ -264,12 +264,15 @@
       serverListenerLauncher =
         forkIO $ catch (serverHandler serverOut context) errorHandler
       server = (Just serverIn, Just serverOut, Nothing, serverProc)
+      msgTimeoutMs = messageTimeout config * 10^6
       serverAndListenerFinalizer tid = do
-        finally (timeout (messageTimeout config * 1^6)
-                         (runSession' exitServer))
-                -- Make sure to kill the listener first, before closing
-                -- handles etc via cleanupProcess
-                (killThread tid >> cleanupProcess server)
+        finally (timeout msgTimeoutMs (runSession' exitServer)) $ do
+          -- Make sure to kill the listener first, before closing
+          -- handles etc via cleanupProcess
+          killThread tid
+          -- Give the server some time to exit cleanly
+          timeout msgTimeoutMs (waitForProcess serverProc)
+          cleanupProcess server
 
   (result, _) <- bracket serverListenerLauncher
                          serverAndListenerFinalizer
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -221,21 +221,13 @@
       contents <- documentContents doc
       liftIO $ contents `shouldSatisfy` T.isPrefixOf "foodule"
 
-  -- describe "getCompletions" $
-  --   it "works" $ runSession serverExe def "test/data/renamePass" $ do
-  --     doc <- openDoc "Desktop/simple.hs" "haskell"
-
-  --     -- wait for module to be loaded
-  --     skipMany loggingNotification
-  --     noDiagnostics
-  --     noDiagnostics
+  describe "getCompletions" $
+    it "works" $ runSession serverExe def "test/data/renamePass" $ do
+      doc <- openDoc "Desktop/simple.hs" "haskell"
 
-  --     comps <- getCompletions doc (Position 5 5)
-  --     let item = head (filter (\x -> x ^. label == "interactWithUser") comps)
-  --     liftIO $ do
-  --       item ^. label `shouldBe` "interactWithUser"
-  --       item ^. kind `shouldBe` Just CiFunction
-  --       item ^. detail `shouldBe` Just "Items -> IO ()\nMain"
+      comps <- getCompletions doc (Position 5 5)
+      let item = head comps
+      liftIO $ item ^. label `shouldBe` "foo"
 
   -- describe "getReferences" $
   --   it "works" $ runSession serverExe fullCaps "test/data/renamePass" $ do
diff --git a/test/dummy-server/Main.hs b/test/dummy-server/Main.hs
--- a/test/dummy-server/Main.hs
+++ b/test/dummy-server/Main.hs
@@ -109,6 +109,13 @@
       send $ RspCodeAction $ makeResponseMessage req caresults
   , didChangeWatchedFilesNotificationHandler = pure $ \_ ->
       send $ NotLogMessage $ fmServerLogMessageNotification MtLog "got workspace/didChangeWatchedFiles"
+  , completionHandler = pure $ \req -> do
+      let res = CompletionList (CompletionListType False (List [item]))
+          item =
+            CompletionItem "foo" (Just CiConstant) (List []) Nothing
+            Nothing Nothing Nothing Nothing Nothing Nothing Nothing
+            Nothing Nothing Nothing Nothing Nothing
+      send $ RspCompletion $ makeResponseMessage req res
   }
   where send msg = readMVar lfvar >>= \lf -> (sendFunc lf) msg
 
