mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2024-09-21 12:19:03 +03:00
add tab tests
This commit is contained in:
parent
50931dd848
commit
a42ef41e8d
@ -246,10 +246,11 @@ viewTabPanel tab selected =
|
||||
++ (if selected then
|
||||
[ -- Used as selector for test queries
|
||||
Attributes.attribute "data-selected" "true"
|
||||
, Attributes.style "display" "block"
|
||||
]
|
||||
|
||||
else
|
||||
[ Attributes.css [ Css.display Css.none ]
|
||||
[ Attributes.style "display" "none"
|
||||
]
|
||||
)
|
||||
)
|
||||
|
@ -118,6 +118,24 @@ pressShiftLeft { targetDetails } =
|
||||
pressKey { targetDetails = targetDetails, keyCode = 37, shiftKey = True }
|
||||
|
||||
|
||||
releaseRightArrow :
|
||||
{ targetDetails : List ( String, Encode.Value ) }
|
||||
-> List Selector
|
||||
-> ProgramTest model msg effect
|
||||
-> ProgramTest model msg effect
|
||||
releaseRightArrow { targetDetails } =
|
||||
releaseKey { targetDetails = targetDetails, keyCode = 39, shiftKey = False }
|
||||
|
||||
|
||||
releaseLeftArrow :
|
||||
{ targetDetails : List ( String, Encode.Value ) }
|
||||
-> List Selector
|
||||
-> ProgramTest model msg effect
|
||||
-> ProgramTest model msg effect
|
||||
releaseLeftArrow { targetDetails } =
|
||||
releaseKey { targetDetails = targetDetails, keyCode = 37, shiftKey = False }
|
||||
|
||||
|
||||
releaseShiftRight :
|
||||
{ targetDetails : List ( String, Encode.Value ) }
|
||||
-> List Selector
|
||||
|
@ -28,7 +28,7 @@ keyboardTests =
|
||||
\() ->
|
||||
Highlightable.initFragments Nothing "Pothos indirect light"
|
||||
|> program marker
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> done
|
||||
, test "has only one element included in the tab sequence" <|
|
||||
\() ->
|
||||
@ -40,55 +40,55 @@ keyboardTests =
|
||||
\() ->
|
||||
Highlightable.initFragments Nothing "Pothos indirect light"
|
||||
|> program marker
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> rightArrow
|
||||
|> ensureFocusOn "indirect"
|
||||
|> ensureTabbable "indirect"
|
||||
|> ensureOnlyOneInTabSequence (String.words "Pothos indirect light")
|
||||
|> rightArrow
|
||||
|> ensureFocusOn "light"
|
||||
|> 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
|
||||
|> ensureFocusOn "light"
|
||||
|> ensureTabbable "light"
|
||||
|> done
|
||||
, test "moves focus left on left arrow key" <|
|
||||
\() ->
|
||||
Highlightable.initFragments Nothing "Pothos indirect light"
|
||||
|> program marker
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> rightArrow
|
||||
|> ensureFocusOn "indirect"
|
||||
|> ensureTabbable "indirect"
|
||||
|> leftArrow
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> 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
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> done
|
||||
, test "moves focus right on shift + right arrow" <|
|
||||
\() ->
|
||||
Highlightable.initFragments Nothing "Pothos indirect light"
|
||||
|> program marker
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> shiftRight
|
||||
|> ensureFocusOn "indirect"
|
||||
|> ensureTabbable "indirect"
|
||||
|> shiftRight
|
||||
|> ensureFocusOn "light"
|
||||
|> ensureTabbable "light"
|
||||
|> shiftRight
|
||||
|> ensureFocusOn "light"
|
||||
|> ensureTabbable "light"
|
||||
|> done
|
||||
, test "moves focus left on shift + left arrow" <|
|
||||
\() ->
|
||||
Highlightable.initFragments Nothing "Pothos indirect light"
|
||||
|> program marker
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> rightArrow
|
||||
|> ensureFocusOn "indirect"
|
||||
|> ensureTabbable "indirect"
|
||||
|> shiftLeft
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> shiftLeft
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> done
|
||||
, test "expands selection one element to the right on shift + right arrow and highlight selected elements" <|
|
||||
\() ->
|
||||
@ -124,13 +124,13 @@ keyboardTests =
|
||||
\() ->
|
||||
Highlightable.initFragments Nothing "Pothos indirect light"
|
||||
|> program marker
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> shiftRight
|
||||
|> releaseShiftRight
|
||||
|> ensureMarked [ "Pothos", " ", "indirect" ]
|
||||
|> ensureFocusOn "indirect"
|
||||
|> ensureTabbable "indirect"
|
||||
|> rightArrow
|
||||
|> ensureFocusOn "light"
|
||||
|> ensureTabbable "light"
|
||||
|> shiftLeft
|
||||
|> releaseShiftLeft
|
||||
|> ensureMarked [ "Pothos", " ", "indirect", " ", "light" ]
|
||||
@ -139,7 +139,7 @@ keyboardTests =
|
||||
\() ->
|
||||
Highlightable.initFragments Nothing "Pothos indirect light"
|
||||
|> program marker
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> mouseDown "Pothos"
|
||||
|> mouseUp "Pothos"
|
||||
|> ensureMarked [ "Pothos" ]
|
||||
@ -148,7 +148,7 @@ keyboardTests =
|
||||
\() ->
|
||||
Highlightable.initFragments Nothing "Pothos indirect light"
|
||||
|> program marker
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> mouseDown "Pothos"
|
||||
|> mouseOver "indirect"
|
||||
|> mouseUp "Pothos"
|
||||
@ -158,7 +158,7 @@ keyboardTests =
|
||||
\() ->
|
||||
Highlightable.initFragments Nothing "Pothos indirect light"
|
||||
|> program marker
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> space
|
||||
|> ensureMarked [ "Pothos" ]
|
||||
|> done
|
||||
@ -166,10 +166,10 @@ keyboardTests =
|
||||
\() ->
|
||||
Highlightable.initFragments Nothing "Pothos indirect light"
|
||||
|> program marker
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> space
|
||||
|> ensureMarked [ "Pothos" ]
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> mouseDown "Pothos"
|
||||
|> mouseUp "Pothos"
|
||||
|> expectViewHasNot
|
||||
@ -178,7 +178,7 @@ keyboardTests =
|
||||
\() ->
|
||||
Highlightable.initFragments Nothing "Pothos indirect light"
|
||||
|> program marker
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> shiftRight
|
||||
|> releaseShiftRight
|
||||
|> ensureMarked [ "Pothos", " ", "indirect" ]
|
||||
@ -190,19 +190,19 @@ keyboardTests =
|
||||
\() ->
|
||||
Highlightable.initFragments Nothing "Pothos indirect light"
|
||||
|> program marker
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> space
|
||||
|> ensureMarked [ "Pothos" ]
|
||||
|> ensureFocusOn "Pothos"
|
||||
|> ensureTabbable "Pothos"
|
||||
|> space
|
||||
|> expectViewHasNot
|
||||
[ Selector.tag "mark" ]
|
||||
]
|
||||
|
||||
|
||||
ensureFocusOn : String -> TestContext marker -> TestContext marker
|
||||
ensureFocusOn word textContext =
|
||||
textContext
|
||||
ensureTabbable : String -> TestContext marker -> TestContext marker
|
||||
ensureTabbable word testContext =
|
||||
testContext
|
||||
|> ensureView
|
||||
(Query.find [ Selector.attribute (Key.tabbable True) ]
|
||||
>> Query.has [ Selector.text word ]
|
||||
@ -210,8 +210,8 @@ ensureFocusOn word textContext =
|
||||
|
||||
|
||||
ensureOnlyOneInTabSequence : List String -> TestContext marker -> TestContext marker
|
||||
ensureOnlyOneInTabSequence words textContext =
|
||||
textContext
|
||||
ensureOnlyOneInTabSequence words testContext =
|
||||
testContext
|
||||
|> ensureView
|
||||
(Query.findAll [ Selector.attribute (Key.tabbable True) ]
|
||||
>> Query.count (Expect.equal 1)
|
||||
@ -223,8 +223,8 @@ ensureOnlyOneInTabSequence words textContext =
|
||||
|
||||
|
||||
ensureMarked : List String -> TestContext marker -> TestContext marker
|
||||
ensureMarked words textContext =
|
||||
textContext
|
||||
ensureMarked words testContext =
|
||||
testContext
|
||||
|> ensureView
|
||||
(Query.find [ Selector.tag "mark" ]
|
||||
>> Query.children [ Selector.tag "span" ]
|
||||
@ -232,6 +232,10 @@ ensureMarked words textContext =
|
||||
)
|
||||
|
||||
|
||||
|
||||
-- TODO: ensure other elements are not marked
|
||||
|
||||
|
||||
space : TestContext marker -> TestContext marker
|
||||
space =
|
||||
KeyboardHelpers.pressSpaceKey { targetDetails = [] }
|
||||
|
221
tests/Spec/Nri/Ui/Tabs.elm
Normal file
221
tests/Spec/Nri/Ui/Tabs.elm
Normal file
@ -0,0 +1,221 @@
|
||||
module Spec.Nri.Ui.Tabs exposing (spec)
|
||||
|
||||
import Accessibility.Key as Key
|
||||
import Accessibility.Role as Role
|
||||
import Browser.Dom as Dom
|
||||
import Expect
|
||||
import Html.Styled as Html exposing (..)
|
||||
import Nri.Ui.Tabs.V7 as Tabs
|
||||
import ProgramTest exposing (..)
|
||||
import Spec.KeyboardHelpers as KeyboardHelpers
|
||||
import Task
|
||||
import Test exposing (..)
|
||||
import Test.Html.Query as Query
|
||||
import Test.Html.Selector as Selector
|
||||
|
||||
|
||||
spec : Test
|
||||
spec =
|
||||
describe "Nri.Ui.Tabs.V7"
|
||||
[ describe "panel rendering" panelRenderingTests
|
||||
, describe "keyboard behavior" keyboardTests
|
||||
]
|
||||
|
||||
|
||||
panelRenderingTests : List Test
|
||||
panelRenderingTests =
|
||||
[ test "displays the associated panel when a tab is activated" <|
|
||||
\() ->
|
||||
program
|
||||
|> ensureTabbable "Tab 0"
|
||||
|> ensurePanelDisplayed "Panel 0"
|
||||
|> done
|
||||
, test "has only one panel displayed" <|
|
||||
\() ->
|
||||
program
|
||||
|> ensureOnlyOnePanelDisplayed [ "Panel 0", "Panel 1", "Panel 2" ]
|
||||
|> done
|
||||
]
|
||||
|
||||
|
||||
keyboardTests : List Test
|
||||
keyboardTests =
|
||||
[ test "has a focusable tab" <|
|
||||
\() ->
|
||||
program
|
||||
|> ensureTabbable "Tab 0"
|
||||
|> done
|
||||
, test "all panels are focusable" <|
|
||||
\() ->
|
||||
program
|
||||
|> ensurePanelsFocusable [ "Panel 0", "Panel 1", "Panel 2" ]
|
||||
|> done
|
||||
, test "has only one tab included in the tab sequence" <|
|
||||
\() ->
|
||||
program
|
||||
|> ensureOnlyOneTabInSequence [ "Tab 0", "Tab 1", "Tab 2" ]
|
||||
|> done
|
||||
, test "moves focus right on right arrow key" <|
|
||||
\() ->
|
||||
program
|
||||
|> ensureTabbable "Tab 0"
|
||||
|> releaseRightArrow
|
||||
|> ensureTabbable "Tab 1"
|
||||
|> ensureOnlyOneTabInSequence [ "Tab 0", "Tab 1", "Tab 2" ]
|
||||
|> releaseRightArrow
|
||||
|> ensureTabbable "Tab 2"
|
||||
|> done
|
||||
, test "moves focus left on left arrow key" <|
|
||||
\() ->
|
||||
program
|
||||
|> ensureTabbable "Tab 0"
|
||||
|> releaseRightArrow
|
||||
|> ensureTabbable "Tab 1"
|
||||
|> releaseLeftArrow
|
||||
|> ensureTabbable "Tab 0"
|
||||
|> ensureOnlyOneTabInSequence [ "Tab 0", "Tab 1", "Tab 2" ]
|
||||
|> done
|
||||
, test "when the focus is on the first element, move focus to the last element on left arrow key" <|
|
||||
\() ->
|
||||
program
|
||||
|> ensureTabbable "Tab 0"
|
||||
|> releaseLeftArrow
|
||||
|> ensureTabbable "Tab 2"
|
||||
|> ensureOnlyOneTabInSequence [ "Tab 0", "Tab 1", "Tab 2" ]
|
||||
|> done
|
||||
, test "when the focus is on the last element, move focus to the first element on right arrow key" <|
|
||||
\() ->
|
||||
program
|
||||
|> ensureTabbable "Tab 0"
|
||||
|> releaseLeftArrow
|
||||
|> ensureTabbable "Tab 2"
|
||||
|> releaseRightArrow
|
||||
|> ensureTabbable "Tab 0"
|
||||
|> ensureOnlyOneTabInSequence [ "Tab 0", "Tab 1", "Tab 2" ]
|
||||
|> done
|
||||
]
|
||||
|
||||
|
||||
type alias TestContext =
|
||||
ProgramTest State Msg ()
|
||||
|
||||
|
||||
ensureTabbable : String -> TestContext -> TestContext
|
||||
ensureTabbable word testContext =
|
||||
testContext
|
||||
|> ensureView
|
||||
(Query.find [ Selector.attribute Role.tab, Selector.attribute (Key.tabbable True) ]
|
||||
>> Query.has [ Selector.text word ]
|
||||
)
|
||||
|
||||
|
||||
ensurePanelsFocusable : List String -> TestContext -> TestContext
|
||||
ensurePanelsFocusable words testContext =
|
||||
testContext
|
||||
|> ensureView
|
||||
(Query.findAll [ Selector.attribute Role.tabPanel, Selector.attribute (Key.tabbable True) ]
|
||||
>> Expect.all (List.indexedMap (\i w -> Query.index i >> Query.has [ Selector.text w ]) words)
|
||||
)
|
||||
|
||||
|
||||
ensurePanelDisplayed : String -> TestContext -> TestContext
|
||||
ensurePanelDisplayed word testContext =
|
||||
testContext
|
||||
|> ensureView
|
||||
(Query.find [ Selector.attribute Role.tabPanel, Selector.style "display" "block" ]
|
||||
>> Query.has [ Selector.text word ]
|
||||
)
|
||||
|
||||
|
||||
ensureOnlyOnePanelDisplayed : List String -> TestContext -> TestContext
|
||||
ensureOnlyOnePanelDisplayed panels testContext =
|
||||
testContext
|
||||
|> ensureView
|
||||
(Query.findAll [ Selector.attribute Role.tabPanel, Selector.style "display" "block" ]
|
||||
>> Query.count (Expect.equal 1)
|
||||
)
|
||||
|> ensureView
|
||||
(Query.findAll [ Selector.attribute Role.tabPanel, Selector.style "display" "none" ]
|
||||
>> Query.count (Expect.equal (List.length panels - 1))
|
||||
)
|
||||
|
||||
|
||||
ensureOnlyOneTabInSequence : List String -> TestContext -> TestContext
|
||||
ensureOnlyOneTabInSequence tabs testContext =
|
||||
testContext
|
||||
|> ensureView
|
||||
(Query.findAll [ Selector.attribute Role.tab, Selector.attribute (Key.tabbable True) ]
|
||||
>> Query.count (Expect.equal 1)
|
||||
)
|
||||
|> ensureView
|
||||
(Query.findAll [ Selector.attribute Role.tab, Selector.attribute (Key.tabbable False) ]
|
||||
>> Query.count (Expect.equal (List.length tabs - 1))
|
||||
)
|
||||
|
||||
|
||||
releaseRightArrow : TestContext -> TestContext
|
||||
releaseRightArrow =
|
||||
KeyboardHelpers.releaseRightArrow { targetDetails = [] }
|
||||
[ Selector.attribute Role.tab, Selector.attribute (Key.tabbable True) ]
|
||||
|
||||
|
||||
releaseLeftArrow : TestContext -> TestContext
|
||||
releaseLeftArrow =
|
||||
KeyboardHelpers.releaseLeftArrow { targetDetails = [] }
|
||||
[ Selector.attribute Role.tab, Selector.attribute (Key.tabbable True) ]
|
||||
|
||||
|
||||
type alias State =
|
||||
{ selected : Int
|
||||
}
|
||||
|
||||
|
||||
init : State
|
||||
init =
|
||||
{ selected = 0
|
||||
}
|
||||
|
||||
|
||||
type Msg
|
||||
= FocusAndSelectTab { select : Int, focus : Maybe String }
|
||||
| Focused (Result Dom.Error ())
|
||||
|
||||
|
||||
update : Msg -> State -> State
|
||||
update msg model =
|
||||
case msg of
|
||||
FocusAndSelectTab { select, focus } ->
|
||||
Tuple.first
|
||||
( { model | selected = select }
|
||||
, focus
|
||||
|> Maybe.map (Dom.focus >> Task.attempt Focused)
|
||||
|> Maybe.withDefault Cmd.none
|
||||
)
|
||||
|
||||
Focused error ->
|
||||
Tuple.first ( model, Cmd.none )
|
||||
|
||||
|
||||
view model =
|
||||
Tabs.view
|
||||
{ title = Nothing
|
||||
, alignment = Tabs.Left
|
||||
, customSpacing = Nothing
|
||||
, focusAndSelect = FocusAndSelectTab
|
||||
, selected = model.selected
|
||||
, tabs =
|
||||
[ Tabs.build { id = 0, idString = "tab-0" } [ Tabs.tabString "Tab 0", Tabs.panelHtml (text "Panel 0") ]
|
||||
, Tabs.build { id = 1, idString = "tab-1" } [ Tabs.tabString "Tab 1", Tabs.panelHtml (text "Panel 1") ]
|
||||
, Tabs.build { id = 2, idString = "tab-2" } [ Tabs.tabString "Tab 2", Tabs.panelHtml (text "Panel 2") ]
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
program : TestContext
|
||||
program =
|
||||
ProgramTest.createSandbox
|
||||
{ init = init
|
||||
, update = update
|
||||
, view = view >> Html.toUnstyled
|
||||
}
|
||||
|> ProgramTest.start ()
|
Loading…
Reference in New Issue
Block a user