@@ -20,6 +20,14 @@
21{-# OPTIONS_GHC -fno-warn-orphans #-}
21{-# OPTIONS_GHC -fno-warn-orphans #-}
23+-- Notice to those working on this test suite:
24+-- It doesn't appear to be possible to use --match to run a particular test, in
25+-- this situation the test may hang before reaching our code. This seems to
26+-- happen when the test is not the first test in the block. As a workaround, you
27+-- can just comment out the other tests. Also, using `xit` will cause the same
28+-- issue. `xit` tests must be the last tests in the session, or the session will
29+-- hang in the following test.
23import Prelude hiding (fail)
31import Prelude hiding (fail)
24import Control.Concurrent
32import Control.Concurrent
25import qualified Control.Concurrent.Async as Async
33import qualified Control.Concurrent.Async as Async
@@ -146,13 +154,13 @@ main = do
146 withDebugging <- isNothing <$> lookupEnv "NO_DEBUG"
154 withDebugging <- isNothing <$> lookupEnv "NO_DEBUG"
147 let wdConfig = WD.defaultConfig { WD.wdPort = fromIntegral $ _selenium_portNumber selenium }
155 let wdConfig = WD.defaultConfig { WD.wdPort = fromIntegral $ _selenium_portNumber selenium }
148 chromeCaps' = WD.getCaps $ chromeConfig browserPath chromeFlags
156 chromeCaps' = WD.getCaps $ chromeConfig browserPath chromeFlags
149− hspec (tests withDebugging wdConfig [chromeCaps'] selenium) `finally` _selenium_stopServer selenium
157+ hspec (tests withDebugging wdConfig [(chromeCaps', "chrome")] selenium) `finally` _selenium_stopServer selenium
151−tests :: Bool -> WD.WDConfig -> [Capabilities] -> Selenium -> Spec
159+tests :: Bool -> WD.WDConfig -> [(Capabilities, String)] -> Selenium -> Spec
152tests withDebugging wdConfig caps _selenium = do
160tests withDebugging wdConfig caps _selenium = do
153 let putStrLnDebug :: MonadIO m => Text -> m ()
161 let putStrLnDebug :: MonadIO m => Text -> m ()
154 putStrLnDebug m = when withDebugging $ liftIO $ putStrLn $ T.unpack m
162 putStrLnDebug m = when withDebugging $ liftIO $ putStrLn $ T.unpack m
155− session' = sessionWith wdConfig "" . using (map (,"") caps)
163+ session' t = sessionWith wdConfig t . using caps
156 runWD m = runWDOptions (WdOptions False) $ do
164 runWD m = runWDOptions (WdOptions False) $ do
157 putStrLnDebug "before"
165 putStrLnDebug "before"
@@ -164,7 +172,7 @@ tests withDebugging wdConfig caps _selenium = do
164 testWidget = testWidgetDebug True withDebugging
172 testWidget = testWidgetDebug True withDebugging
165 testWidget' :: WD a -> (a -> WD b) -> (forall m js. TestWidget js (SpiderTimeline Global) m => m ()) -> WD b
173 testWidget' :: WD a -> (a -> WD b) -> (forall m js. TestWidget js (SpiderTimeline Global) m => m ()) -> WD b
166 testWidget' = testWidgetDebug' True withDebugging
174 testWidget' = testWidgetDebug' True withDebugging
167− describe "text" $ session' $ do
175+ session' "text" $ do
168 it "works" $ runWD $ do
176 it "works" $ runWD $ do
169 testWidgetStatic (checkBodyText "hello world") $ do
177 testWidgetStatic (checkBodyText "hello world") $ do
170 text "hello world"
178 text "hello world"
@@ -225,7 +233,7 @@ tests withDebugging wdConfig caps _selenium = do
225 click <- button ""
233 click <- button ""
226 void $ textNode $ TextNodeConfig "initial" $ Just $ "after" <$ click
234 void $ textNode $ TextNodeConfig "initial" $ Just $ "after" <$ click
228− describe "element" $ session' $ do
236+ session' "element" $ do
229 it "works with domEvent Click" $ runWD $ do
237 it "works with domEvent Click" $ runWD $ do
230 clickedRef <- liftIO $ newRef False
238 clickedRef <- liftIO $ newRef False
231 testWidget' (findElemWithRetry $ WD.ByTag "div") WD.click $ do
239 testWidget' (findElemWithRetry $ WD.ByTag "div") WD.click $ do
@@ -289,8 +297,8 @@ tests withDebugging wdConfig caps _selenium = do
289 let click = domEvent Click e
297 let click = domEvent Click e
290 return ()
298 return ()
292− describe "inputElement" $ do
300+ session' "inputElement" $ do
293− describe "static renderer" $ session' $ do
301+ describe "static renderer" $ do
294 it "sets value attribute" $ runWD $ do
302 it "sets value attribute" $ runWD $ do
295 let checkStatic = do
303 let checkStatic = do
296 e <- findElemWithRetry $ WD.ByTag "input"
304 e <- findElemWithRetry $ WD.ByTag "input"
@@ -347,7 +355,7 @@ tests withDebugging wdConfig caps _selenium = do
347 & inputElementConfig_initialChecked .~ False
355 & inputElementConfig_initialChecked .~ False
348 & inputElementConfig_setChecked .~ (True <$ pb)
356 & inputElementConfig_setChecked .~ (True <$ pb)
350− describe "hydration" $ session' $ do
358+ describe "hydration" $ do
351 it "doesn't wipe user input when switching over" $ runWD $ do
359 it "doesn't wipe user input when switching over" $ runWD $ do
352 inputRef <- newRef ("hello " :: Text)
360 inputRef <- newRef ("hello " :: Text)
353 testWidget'
361 testWidget'
@@ -585,8 +593,7 @@ tests withDebugging wdConfig caps _selenium = do
585 el "p" $ dynText $ _inputElement_value e
593 el "p" $ dynText $ _inputElement_value e
586 performEvent_ $ consRef valRef <$> updated (_inputElement_value e)
594 performEvent_ $ consRef valRef <$> updated (_inputElement_value e)
587 performEvent_ $ consRef inputRef <$> _inputElement_input e
595 performEvent_ $ consRef inputRef <$> _inputElement_input e
589− describe "hydration/immediate" $ session' $ do
596+ describe "hydration/immediate" $ do
590 it "captures user input after switchover" $ runWD $ do
597 it "captures user input after switchover" $ runWD $ do
591 inputRef :: IORef Text <- newRef ""
598 inputRef :: IORef Text <- newRef ""
592 let checkValue = do
599 let checkValue = do
@@ -666,8 +673,8 @@ tests withDebugging wdConfig caps _selenium = do
666 names <- liftJSM $ traverse File.getName fs
673 names <- liftJSM $ traverse File.getName fs
667 liftIO $ writeRef filesRef names
674 liftIO $ writeRef filesRef names
669− describe "textAreaElement" $ do
676+ session' "textAreaElement" $ do
670− describe "static renderer" $ session' $ do
677+ describe "static renderer" $ do
671 it "sets value attribute" $ runWD $ do
678 it "sets value attribute" $ runWD $ do
672 let checkStatic = do
679 let checkStatic = do
673 e <- findElemWithRetry $ WD.ByTag "textarea"
680 e <- findElemWithRetry $ WD.ByTag "textarea"
@@ -690,7 +697,7 @@ tests withDebugging wdConfig caps _selenium = do
690 & textAreaElementConfig_initialValue .~ "test"
697 & textAreaElementConfig_initialValue .~ "test"
691 & textAreaElementConfig_setValue .~ ("test-updated" <$ pb)
698 & textAreaElementConfig_setValue .~ ("test-updated" <$ pb)
693− describe "hydration" $ session' $ do
700+ describe "hydration" $ do
694 it "doesn't wipe user input when switching over" $ runWD $ do
701 it "doesn't wipe user input when switching over" $ runWD $ do
695 inputRef <- newRef ("" :: Text)
702 inputRef <- newRef ("" :: Text)
696 testWidget'
703 testWidget'
@@ -839,7 +846,7 @@ tests withDebugging wdConfig caps _selenium = do
839 e <- textAreaElement $ def & textAreaElementConfig_setValue .~ ("pb" <$ pb)
846 e <- textAreaElement $ def & textAreaElementConfig_setValue .~ ("pb" <$ pb)
840 el "p" $ dynText $ _textAreaElement_value e
847 el "p" $ dynText $ _textAreaElement_value e
842− describe "hydration/immediate" $ session' $ do
849+ describe "hydration/immediate" $ do
843 it "captures user input after switchover" $ runWD $ do
850 it "captures user input after switchover" $ runWD $ do
844 inputRef :: IORef Text <- newRef ""
851 inputRef :: IORef Text <- newRef ""
845 let checkValue = do
852 let checkValue = do
@@ -881,13 +888,13 @@ tests withDebugging wdConfig caps _selenium = do
881 performEvent_ $ liftIO . writeRef valueByUIRef <$> _textAreaElement_input e
888 performEvent_ $ liftIO . writeRef valueByUIRef <$> _textAreaElement_input e
882 performEvent_ $ liftIO . writeRef valueRef <$> updated (value e)
889 performEvent_ $ liftIO . writeRef valueRef <$> updated (value e)
884− describe "selectElement" $ do
891+ session' "selectElement" $ do
885 let options :: DomBuilder t m => m ()
892 let options :: DomBuilder t m => m ()
886 options = do
893 options = do
887 elAttr "option" ("value" =: "one" <> "id" =: "one") $ text "one"
894 elAttr "option" ("value" =: "one" <> "id" =: "one") $ text "one"
888 elAttr "option" ("value" =: "two" <> "id" =: "two") $ text "two"
895 elAttr "option" ("value" =: "two" <> "id" =: "two") $ text "two"
889 elAttr "option" ("value" =: "three" <> "id" =: "three") $ text "three"
896 elAttr "option" ("value" =: "three" <> "id" =: "three") $ text "three"
890− describe "hydration" $ session' $ do
897+ describe "hydration" $ do
891 it "sets initial value correctly" $ runWD $ do
898 it "sets initial value correctly" $ runWD $ do
892 inputRef <- newRef ("" :: Text)
899 inputRef <- newRef ("" :: Text)
893 let setup = do
900 let setup = do
@@ -961,7 +968,7 @@ tests withDebugging wdConfig caps _selenium = do
961 performEvent_ $ liftIO . writeRef valueByUIRef <$> _selectElement_change e
968 performEvent_ $ liftIO . writeRef valueByUIRef <$> _selectElement_change e
962 performEvent_ $ liftIO . writeRef valueRef <$> updated (_selectElement_value e)
969 performEvent_ $ liftIO . writeRef valueRef <$> updated (_selectElement_value e)
964− describe "hydration/immediate" $ session' $ do
971+ describe "hydration/immediate" $ do
965 it "captures user input after switchover" $ runWD $ do
972 it "captures user input after switchover" $ runWD $ do
966 inputRef :: IORef Text <- newRef ""
973 inputRef :: IORef Text <- newRef ""
967 let checkValue = do
974 let checkValue = do
@@ -1007,7 +1014,7 @@ tests withDebugging wdConfig caps _selenium = do
1007 performEvent_ $ liftIO . writeRef valueByUIRef <$> _selectElement_change e
1014 performEvent_ $ liftIO . writeRef valueByUIRef <$> _selectElement_change e
1008 performEvent_ $ liftIO . writeRef valueRef <$> updated (_selectElement_value e)
1015 performEvent_ $ liftIO . writeRef valueRef <$> updated (_selectElement_value e)
1010− describe "prerender" $ session' $ do
1017+ session' "prerender" $ do
1011 it "works in simple case" $ runWD $ do
1018 it "works in simple case" $ runWD $ do
1012 testWidget (checkBodyText "One") (checkBodyText "Two") $ do
1019 testWidget (checkBodyText "One") (checkBodyText "Two") $ do
1013 prerender_ (text "One") (text "Two")
1020 prerender_ (text "One") (text "Two")
@@ -1076,7 +1083,7 @@ tests withDebugging wdConfig caps _selenium = do
1076 prerender_ (pure ()) (liftIO $ trigger "Client")
1083 prerender_ (pure ()) (liftIO $ trigger "Client")
1077 textNode $ TextNodeConfig "Initial" $ Just e
1084 textNode $ TextNodeConfig "Initial" $ Just e
1079− describe "namespaces" $ session' $ do
1086+ session' "namespaces" $ do
1080 it "dyn can be nested in namespaced widget" $ runWD $ do
1087 it "dyn can be nested in namespaced widget" $ runWD $ do
1081 testWidget (pure ()) (checkTextInTag "svg" "one") $ do
1088 testWidget (pure ()) (checkTextInTag "svg" "one") $ do
1082 let svgRootCfg = def
1089 let svgRootCfg = def
@@ -1085,7 +1092,7 @@ tests withDebugging wdConfig caps _selenium = do
1085 void $ element "svg" svgRootCfg $ do
1092 void $ element "svg" svgRootCfg $ do
1086 dyn_ $ text "one" <$ pure ()
1093 dyn_ $ text "one" <$ pure ()
1088− describe "runWithReplace" $ session' $ do
1095+ session' "runWithReplace" $ do
1089 it "works" $ runWD $ do
1096 it "works" $ runWD $ do
1090 replaceChan :: Chan Text <- liftIO newChan
1097 replaceChan :: Chan Text <- liftIO newChan
1091 let setup = findElemWithRetry $ WD.ByTag "div"
1098 let setup = findElemWithRetry $ WD.ByTag "div"
@@ -1283,7 +1290,7 @@ tests withDebugging wdConfig caps _selenium = do
1283 _ <- runWithReplace (text "inner1") $ el "p" (text "inner2") <$ replace
1290 _ <- runWithReplace (text "inner1") $ el "p" (text "inner2") <$ replace
1284 text "|after"
1291 text "|after"
1286− describe "traverseDMapWithKeyWithAdjust" $ session' $ do
1293+ session' "traverseDMapWithKeyWithAdjust" $ do
1287 let widget :: DomBuilder t m => DKey a -> Identity a -> m (Identity a)
1294 let widget :: DomBuilder t m => DKey a -> Identity a -> m (Identity a)
1288 widget k (Identity v) = elAttr "li" ("id" =: textKey k) $ do
1295 widget k (Identity v) = elAttr "li" ("id" =: textKey k) $ do
1289 elClass "span" "key" $ text $ textKey k
1296 elClass "span" "key" $ text $ textKey k
@@ -1386,7 +1393,7 @@ tests withDebugging wdConfig caps _selenium = do
1386 (dmap, _evt) <- traverseDMapWithKeyWithAdjust widget keyMap $ leftmost [postBuildPatch <$ pb, replace]
1393 (dmap, _evt) <- traverseDMapWithKeyWithAdjust widget keyMap $ leftmost [postBuildPatch <$ pb, replace]
1387 liftIO $ dmap `H.shouldBe` keyMap
1394 liftIO $ dmap `H.shouldBe` keyMap
1389− describe "traverseIntMapWithKeyWithAdjust" $ session' $ do
1396+ session' "traverseIntMapWithKeyWithAdjust" $ do
1390 let textKeyInt k = "key" <> T.pack (show k)
1397 let textKeyInt k = "key" <> T.pack (show k)
1391 intMap = IntMap.fromList
1398 intMap = IntMap.fromList
1392 [ (1, "one")
1399 [ (1, "one")
@@ -1493,7 +1500,7 @@ tests withDebugging wdConfig caps _selenium = do
1493 (dmap, _evt) <- traverseIntMapWithKeyWithAdjust widget intMap $ leftmost [postBuildPatch <$ pb, replace]
1500 (dmap, _evt) <- traverseIntMapWithKeyWithAdjust widget intMap $ leftmost [postBuildPatch <$ pb, replace]
1494 liftIO $ dmap `H.shouldBe` intMap
1501 liftIO $ dmap `H.shouldBe` intMap
1496− describe "traverseDMapWithKeyWithAdjustWithMove" $ session' $ do
1503+ session' "traverseDMapWithKeyWithAdjustWithMove" $ do
1497 let widget :: DomBuilder t m => Key2 a -> Identity a -> m (Identity a)
1504 let widget :: DomBuilder t m => Key2 a -> Identity a -> m (Identity a)
1498 widget k (Identity v) = elAttr "li" ("id" =: textKey2 k) $ do
1505 widget k (Identity v) = elAttr "li" ("id" =: textKey2 k) $ do
1499 elClass "span" "key" $ text $ textKey2 k
1506 elClass "span" "key" $ text $ textKey2 k
@@ -1573,8 +1580,8 @@ tests withDebugging wdConfig caps _selenium = do
1573 (dmap, _evt) <- traverseDMapWithKeyWithAdjustWithMove widget initMap =<< triggerEventWithChan chan
1580 (dmap, _evt) <- traverseDMapWithKeyWithAdjustWithMove widget initMap =<< triggerEventWithChan chan
1574 liftIO $ assertEqual "DMap" initMap dmap
1581 liftIO $ assertEqual "DMap" initMap dmap
1576− describe "hydrating invalid HTML" $ session' $ do
1583+ session' "hydrating invalid HTML" $ do
1577− it "can hydrate list in paragraph" $ runWD $ do
1584+ xit "can hydrate list in paragraph" $ runWD $ do
1578 let preSwitchover = do
1585 let preSwitchover = do
1579 checkBodyText "before\ninner\nafter"
1586 checkBodyText "before\ninner\nafter"
1580 -- Two <p> tags should be present
1587 -- Two <p> tags should be present
@@ -1603,7 +1610,7 @@ tests withDebugging wdConfig caps _selenium = do
1603 -- TODO: This test presupposes the exact set of labels that "dropdown" places in the "value" fields to distinguish options.
1610 -- TODO: This test presupposes the exact set of labels that "dropdown" places in the "value" fields to distinguish options.
1604 -- This dependence on internal implementation details is undesirable in a test case, but seems fairly tricky to avoid.
1611 -- This dependence on internal implementation details is undesirable in a test case, but seems fairly tricky to avoid.
1605 -- It seems expedient for the time being to expect this test case to be updated, should those implementation details ever change.
1612 -- It seems expedient for the time being to expect this test case to be updated, should those implementation details ever change.
1606− describe "dropdown" $ session' $ do
1613+ session' "dropdown" $ do
1607 let doTest expectedOpts (initialValue :: Text) = do
1614 let doTest expectedOpts (initialValue :: Text) = do
1608 let doCheck = do
1615 let doCheck = do
1609 es <- findElemsWithRetry $ WD.ByTag "option"
1616 es <- findElemsWithRetry $ WD.ByTag "option"