@@ -432,6 +432,133 @@ main = hspec $ parallel $ do
432432 names <- liftJSM $ traverse File.getName fs
433433 liftIO $ writeIORef filesRef names
434434
435+ describe "textAreaElement" $ parallel $ do
436+ describe "hydration" $ do
437+ it "doesn't wipe user input when switching over" $ do
438+ inputRef <- newIORef ""
439+ testWidget'
440+ (do
441+ e <- WD.findElem $ WD.ByTag "input"
442+ WD.sendKeys "hello world" e
443+ pure e)
444+ (\e -> do
445+ t <- WD.attr e "value"
446+ liftIO $ t `shouldBe` Just "hello world"
447+ WD.click <=< WD.findElem $ WD.ByTag "button"
448+ input <- liftIO $ readIORef inputRef
449+ liftIO $ input `shouldBe` "hello world"
450+ ) $ do
451+ e <- textAreaElement def
452+ click <- button "save"
453+ performEvent_ $ liftIO . writeIORef inputRef <$> tag (current (value e)) click
454+ it "captures user input after switchover" $ do
455+ inputRef <- newIORef ""
456+ let checkValue = do
457+ WD.sendKeys "hello world" <=< WD.findElem $ WD.ByTag "input"
458+ WD.click <=< WD.findElem $ WD.ByTag "button"
459+ input <- liftIO $ readIORef inputRef
460+ liftIO $ input `shouldBe` "hello world"
461+ testWidget (pure ()) checkValue $ do
462+ e <- textAreaElement def
463+ click <- button "save"
464+ performEvent_ $ liftIO . writeIORef inputRef <$> tag (current (value e)) click
465+ it "sets focus appropriately" $ do
466+ focusRef <- newIORef False
467+ let checkValue = do
468+ liftIO $ readIORef focusRef >>= flip shouldBe False
469+ e <- WD.findElem $ WD.ByTag "input"
470+ WD.click e
471+ liftIO $ threadDelay 100000
472+ liftIO $ readIORef focusRef >>= flip shouldBe True
473+ testWidget (pure ()) checkValue $ do
474+ e <- textAreaElement def
475+ performEvent_ $ liftIO . writeIORef focusRef <$> updated (_textAreaElement_hasFocus e)
476+ it "sets focus when focus occurs before hydration" $ do
477+ focusRef <- newIORef False
478+ let setup = do
479+ e <- WD.findElem $ WD.ByTag "input"
480+ WD.click e
481+ hasFocus <- (== e) <$> WD.activeElem
482+ liftIO $ do
483+ hasFocus `shouldBe` True
484+ readIORef focusRef >>= flip shouldBe False
485+ check = liftIO $ readIORef focusRef >>= flip shouldBe True
486+ testWidget setup check $ do
487+ e <- textAreaElement def
488+ performEvent_ $ liftIO . writeIORef focusRef <$> updated (_textAreaElement_hasFocus e)
489+ it "sets value appropriately" $ do
490+ valueByUIRef <- newIORef ("" :: Text)
491+ valueRef <- newIORef ("" :: Text)
492+ setValueChan :: Chan Text <- newChan
493+ let checkValue = do
494+ liftIO $ readIORef valueByUIRef >>= flip shouldBe ""
495+ liftIO $ readIORef valueRef >>= flip shouldBe ""
496+ e <- WD.findElem $ WD.ByTag "input"
497+ WD.sendKeys "hello" e
498+ liftIO $ do
499+ threadDelay 100000
500+ readIORef valueByUIRef >>= flip shouldBe "hello"
501+ readIORef valueRef >>= flip shouldBe "hello"
502+ writeChan setValueChan "world"
503+ threadDelay 100000
504+ readIORef valueByUIRef >>= flip shouldBe "hello"
505+ readIORef valueRef >>= flip shouldBe "world"
506+ testWidget (pure ()) checkValue $ do
507+ (setValue', triggerSetValue) <- newTriggerEvent
508+ prerender (pure ()) $ liftIO $ void $ forkIO $ forever $ do
509+ triggerSetValue =<< readChan setValueChan
510+ e <- textAreaElement $ def { _textAreaElementConfig_setValue = Just setValue' }
511+ performEvent_ $ liftIO . writeIORef valueByUIRef <$> _textAreaElement_input e
512+ performEvent_ $ liftIO . writeIORef valueRef <$> updated (value e)
513+
514+ describe "hydration/immediate" $ do
515+ it "captures user input after switchover" $ do
516+ inputRef :: IORef Text <- newIORef ""
517+ let checkValue = do
518+ WD.sendKeys "hello world" <=< WD.findElem $ WD.ByTag "input"
519+ WD.click <=< WD.findElem $ WD.ByTag "button"
520+ input <- liftIO $ readIORef inputRef
521+ liftIO $ input `shouldBe` "hello world"
522+ testWidget (pure ()) checkValue $ prerender (pure ()) $ do
523+ e <- textAreaElement def
524+ click <- button "save"
525+ performEvent_ $ liftIO . writeIORef inputRef <$> tag (current (value e)) click
526+ it "sets focus appropriately" $ do
527+ focusRef <- newIORef False
528+ let checkValue = do
529+ liftIO $ readIORef focusRef >>= flip shouldBe False
530+ e <- WD.findElem $ WD.ByTag "input"
531+ WD.click e
532+ liftIO $ threadDelay 100000
533+ liftIO $ readIORef focusRef >>= flip shouldBe True
534+ testWidget (pure ()) checkValue $ prerender (pure ()) $ do
535+ e <- textAreaElement def
536+ performEvent_ $ liftIO . writeIORef focusRef <$> updated (_textAreaElement_hasFocus e)
537+ it "sets value appropriately" $ do
538+ valueByUIRef :: IORef Text <- newIORef ""
539+ valueRef :: IORef Text <- newIORef ""
540+ setValueChan :: Chan Text <- newChan
541+ let checkValue = do
542+ liftIO $ readIORef valueByUIRef >>= flip shouldBe ""
543+ liftIO $ readIORef valueRef >>= flip shouldBe ""
544+ e <- WD.findElem $ WD.ByTag "input"
545+ WD.sendKeys "hello" e
546+ liftIO $ do
547+ threadDelay 100000
548+ readIORef valueByUIRef >>= flip shouldBe "hello"
549+ readIORef valueRef >>= flip shouldBe "hello"
550+ writeChan setValueChan "world"
551+ threadDelay 100000
552+ readIORef valueByUIRef >>= flip shouldBe "hello"
553+ readIORef valueRef >>= flip shouldBe "world"
554+ testWidget (pure ()) checkValue $ prerender (pure ()) $ do
555+ (setValue', triggerSetValue) <- newTriggerEvent
556+ prerender (pure ()) $ liftIO $ void $ forkIO $ forever $ do
557+ triggerSetValue =<< readChan setValueChan
558+ e <- textAreaElement $ def { _textAreaElementConfig_setValue = Just setValue' }
559+ performEvent_ $ liftIO . writeIORef valueByUIRef <$> _textAreaElement_input e
560+ performEvent_ $ liftIO . writeIORef valueRef <$> updated (value e)
561+
435562 describe "prerender" $ parallel $ do
436563 it "works in simple case" $ do
437564 testWidget (checkBodyText "One") (checkBodyText "Two") $ do