mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2024-09-21 20:27:36 +03:00
330 lines
12 KiB
Elm
330 lines
12 KiB
Elm
module Spec.Nri.Ui.Highlighter exposing (spec)
|
|
|
|
import Accessibility.Key as Key
|
|
import Expect
|
|
import Html.Styled exposing (toUnstyled)
|
|
import Nri.Ui.Colors.V1 as Colors
|
|
import Nri.Ui.Highlightable.V1 as Highlightable exposing (Highlightable)
|
|
import Nri.Ui.Highlighter.V1 as Highlighter
|
|
import Nri.Ui.HighlighterTool.V1 as Tool exposing (Tool)
|
|
import ProgramTest exposing (..)
|
|
import Spec.KeyboardHelpers as KeyboardHelpers
|
|
import Spec.MouseHelpers as MouseHelpers
|
|
import Test exposing (..)
|
|
import Test.Html.Query as Query
|
|
import Test.Html.Selector as Selector
|
|
|
|
|
|
spec : Test
|
|
spec =
|
|
describe "Nri.Ui.Highlighter.V1"
|
|
[ describe "keyboard behavior" keyboardTests
|
|
]
|
|
|
|
|
|
keyboardTests : List Test
|
|
keyboardTests =
|
|
[ test "has a focusable element when there is one" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> ensureTabbable "Pothos"
|
|
|> done
|
|
, test "has only one element included in the tab sequence" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> ensureOnlyOneInTabSequence (String.words "Pothos indirect light")
|
|
|> done
|
|
, test "moves focus right on right arrow key" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> ensureTabbable "Pothos"
|
|
|> rightArrow
|
|
|> ensureTabbable "indirect"
|
|
|> ensureOnlyOneInTabSequence (String.words "Pothos indirect light")
|
|
|> rightArrow
|
|
|> ensureTabbable "light"
|
|
-- once we're on the final element, pressing right arrow again should
|
|
-- _not_ wrap the focus. We should stay right where we are!
|
|
|> rightArrow
|
|
|> ensureTabbable "light"
|
|
|> done
|
|
, test "moves focus left on left arrow key" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> ensureTabbable "Pothos"
|
|
|> rightArrow
|
|
|> ensureTabbable "indirect"
|
|
|> leftArrow
|
|
|> ensureTabbable "Pothos"
|
|
|> ensureOnlyOneInTabSequence (String.words "Pothos indirect light")
|
|
-- once we're on the first element, pressing left arrow again should
|
|
-- _not_ wrap the focus. We should stay right where we are!
|
|
|> leftArrow
|
|
|> ensureTabbable "Pothos"
|
|
|> done
|
|
, test "moves focus right on shift + right arrow" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> ensureTabbable "Pothos"
|
|
|> shiftRight
|
|
|> ensureTabbable "indirect"
|
|
|> shiftRight
|
|
|> ensureTabbable "light"
|
|
|> shiftRight
|
|
|> ensureTabbable "light"
|
|
|> done
|
|
, test "moves focus left on shift + left arrow" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> ensureTabbable "Pothos"
|
|
|> rightArrow
|
|
|> ensureTabbable "indirect"
|
|
|> shiftLeft
|
|
|> ensureTabbable "Pothos"
|
|
|> shiftLeft
|
|
|> ensureTabbable "Pothos"
|
|
|> done
|
|
, test "expands selection one element to the right on shift + right arrow and highlight selected elements" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> shiftRight
|
|
|> releaseShiftRight
|
|
|> ensureMarked [ "Pothos", " ", "indirect" ]
|
|
|> shiftRight
|
|
|> releaseShiftRight
|
|
|> ensureMarked [ "Pothos", " ", "indirect", " ", "light" ]
|
|
|> shiftRight
|
|
|> releaseShiftRight
|
|
|> ensureMarked [ "Pothos", " ", "indirect", " ", "light" ]
|
|
|> done
|
|
, test "expands selection one element to the left on shift + left arrow and highlight selected elements" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> rightArrow
|
|
|> rightArrow
|
|
|> shiftLeft
|
|
|> releaseShiftLeft
|
|
|> ensureMarked [ "indirect", " ", "light" ]
|
|
|> shiftLeft
|
|
|> releaseShiftLeft
|
|
|> ensureMarked [ "Pothos", " ", "indirect", " ", "light" ]
|
|
|> shiftLeft
|
|
|> releaseShiftLeft
|
|
|> ensureMarked [ "Pothos", " ", "indirect", " ", "light" ]
|
|
|> done
|
|
, test "merges highlights" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> ensureTabbable "Pothos"
|
|
|> shiftRight
|
|
|> releaseShiftRight
|
|
|> ensureMarked [ "Pothos", " ", "indirect" ]
|
|
|> ensureTabbable "indirect"
|
|
|> rightArrow
|
|
|> ensureTabbable "light"
|
|
|> shiftLeft
|
|
|> releaseShiftLeft
|
|
|> ensureMarked [ "Pothos", " ", "indirect", " ", "light" ]
|
|
|> done
|
|
, test "selects element on MouseDown and highlights selected element on MouseUp" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> ensureTabbable "Pothos"
|
|
|> mouseDown "Pothos"
|
|
|> mouseUp "Pothos"
|
|
|> ensureMarked [ "Pothos" ]
|
|
|> done
|
|
, test "selects element on MouseDown, expands selection on MouseOver, and highlights selected elements on MouseUp" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> ensureTabbable "Pothos"
|
|
|> mouseDown "Pothos"
|
|
|> mouseOver "indirect"
|
|
|> mouseUp "Pothos"
|
|
|> ensureMarked [ "Pothos", " ", "indirect" ]
|
|
|> done
|
|
, test "Highlights element on Space" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> ensureTabbable "Pothos"
|
|
|> space
|
|
|> ensureMarked [ "Pothos" ]
|
|
|> done
|
|
, test "Removes highlight from element on MouseUp" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> ensureTabbable "Pothos"
|
|
|> space
|
|
|> ensureMarked [ "Pothos" ]
|
|
|> ensureTabbable "Pothos"
|
|
|> mouseDown "Pothos"
|
|
|> mouseUp "Pothos"
|
|
|> expectViewHasNot
|
|
[ Selector.tag "mark" ]
|
|
, test "Removes entire highlight from a group of elements on MouseUp" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> ensureTabbable "Pothos"
|
|
|> shiftRight
|
|
|> releaseShiftRight
|
|
|> ensureMarked [ "Pothos", " ", "indirect" ]
|
|
|> mouseDown "indirect"
|
|
|> mouseUp "indirect"
|
|
|> expectViewHasNot
|
|
[ Selector.tag "mark" ]
|
|
, test "Removes highlight from element on Space" <|
|
|
\() ->
|
|
Highlightable.initFragments Nothing "Pothos indirect light"
|
|
|> program marker
|
|
|> ensureTabbable "Pothos"
|
|
|> space
|
|
|> ensureMarked [ "Pothos" ]
|
|
|> ensureTabbable "Pothos"
|
|
|> space
|
|
|> expectViewHasNot
|
|
[ Selector.tag "mark" ]
|
|
]
|
|
|
|
|
|
ensureTabbable : String -> TestContext marker -> TestContext marker
|
|
ensureTabbable word testContext =
|
|
testContext
|
|
|> ensureView
|
|
(Query.find [ Selector.attribute (Key.tabbable True) ]
|
|
>> Query.has [ Selector.text word ]
|
|
)
|
|
|
|
|
|
ensureOnlyOneInTabSequence : List String -> TestContext marker -> TestContext marker
|
|
ensureOnlyOneInTabSequence words testContext =
|
|
testContext
|
|
|> ensureView
|
|
(Query.findAll [ Selector.attribute (Key.tabbable True) ]
|
|
>> Query.count (Expect.equal 1)
|
|
)
|
|
|> ensureView
|
|
(Query.findAll [ Selector.attribute (Key.tabbable False) ]
|
|
>> Query.count (Expect.equal (List.length words - 1))
|
|
)
|
|
|
|
|
|
ensureMarked : List String -> TestContext marker -> TestContext marker
|
|
ensureMarked words testContext =
|
|
testContext
|
|
|> ensureView
|
|
(Query.find [ Selector.tag "mark" ]
|
|
>> Query.children [ Selector.tag "span" ]
|
|
>> Expect.all (List.indexedMap (\i w -> Query.index i >> Query.has [ Selector.text w ]) words)
|
|
)
|
|
|
|
|
|
|
|
-- TODO: ensure other elements are not marked
|
|
|
|
|
|
space : TestContext marker -> TestContext marker
|
|
space =
|
|
KeyboardHelpers.pressSpaceKey { targetDetails = [] }
|
|
[ Selector.attribute (Key.tabbable True) ]
|
|
|
|
|
|
rightArrow : TestContext marker -> TestContext marker
|
|
rightArrow =
|
|
KeyboardHelpers.pressRightArrow { targetDetails = [] }
|
|
[ Selector.attribute (Key.tabbable True) ]
|
|
|
|
|
|
leftArrow : TestContext marker -> TestContext marker
|
|
leftArrow =
|
|
KeyboardHelpers.pressLeftArrow { targetDetails = [] }
|
|
[ Selector.attribute (Key.tabbable True) ]
|
|
|
|
|
|
shiftRight : TestContext marker -> TestContext marker
|
|
shiftRight =
|
|
KeyboardHelpers.pressShiftRight { targetDetails = [] }
|
|
[ Selector.attribute (Key.tabbable True) ]
|
|
|
|
|
|
shiftLeft : TestContext marker -> TestContext marker
|
|
shiftLeft =
|
|
KeyboardHelpers.pressShiftLeft { targetDetails = [] }
|
|
[ Selector.attribute (Key.tabbable True) ]
|
|
|
|
|
|
releaseShiftRight : TestContext marker -> TestContext marker
|
|
releaseShiftRight =
|
|
KeyboardHelpers.releaseShiftRight { targetDetails = [] }
|
|
[ Selector.attribute (Key.tabbable True) ]
|
|
|
|
|
|
releaseShiftLeft : TestContext marker -> TestContext marker
|
|
releaseShiftLeft =
|
|
KeyboardHelpers.releaseShiftLeft { targetDetails = [] }
|
|
[ Selector.attribute (Key.tabbable True) ]
|
|
|
|
|
|
mouseDown : String -> TestContext marker -> TestContext marker
|
|
mouseDown word =
|
|
MouseHelpers.cancelableMouseDown [ Selector.tag "span", Selector.containing [ Selector.text word ] ]
|
|
|
|
|
|
mouseUp : String -> TestContext marker -> TestContext marker
|
|
mouseUp word =
|
|
MouseHelpers.cancelableMouseUp [ Selector.tag "span", Selector.containing [ Selector.text word ] ]
|
|
|
|
|
|
mouseOver : String -> TestContext marker -> TestContext marker
|
|
mouseOver word =
|
|
MouseHelpers.cancelableMouseOver [ Selector.tag "span", Selector.containing [ Selector.text word ] ]
|
|
|
|
|
|
marker : Tool ()
|
|
marker =
|
|
Tool.Marker
|
|
(Tool.buildMarker
|
|
{ highlightColor = Colors.magenta
|
|
, hoverColor = Colors.magenta
|
|
, hoverHighlightColor = Colors.magenta
|
|
, kind = ()
|
|
, name = Nothing
|
|
}
|
|
)
|
|
|
|
|
|
type alias TestContext marker =
|
|
ProgramTest (Highlighter.Model marker) (Highlighter.Msg marker) ()
|
|
|
|
|
|
program : Tool marker -> List (Highlightable marker) -> TestContext marker
|
|
program tool highlightables =
|
|
ProgramTest.createSandbox
|
|
{ init =
|
|
Highlighter.init
|
|
{ id = "test-highlighter-container"
|
|
, highlightables = highlightables
|
|
, marker = tool
|
|
}
|
|
, update =
|
|
\msg model ->
|
|
case Highlighter.update msg model of
|
|
( newModel, _, _ ) ->
|
|
newModel
|
|
, view = Highlighter.view >> toUnstyled
|
|
}
|
|
|> ProgramTest.start ()
|