123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- import { haveClasses, beVisible, haveAttribute, haveText, html, notBeVisible, notExist, test, haveFocus, notHaveClasses, notHaveAttribute } from '../../../utils'
- test('it works',
- [html`
- <div x-data x-menu>
- <span>
- <button x-menu:button trigger>
- <span>Options</span>
- </button>
- </span>
- <div x-menu:items items>
- <div>
- <p>Signed in as</p>
- <p>tom@example.com</p>
- </div>
- <div>
- <a x-menu:item href="#account-settings">
- Account settings
- </a>
- <a x-menu:item href="#support">
- Support
- </a>
- <a x-menu:item disabled href="#new-feature">
- New feature (soon)
- </a>
- <a x-menu:item href="#license">
- License
- </a>
- </div>
- <div>
- <a x-menu:item href="#sign-out">
- Sign out
- </a>
- </div>
- </div>
- </div>`],
- ({ get }) => {
- get('[items]').should(notBeVisible())
- get('[trigger]').click()
- get('[items]').should(beVisible())
- },
- )
- test('focusing away closes menu',
- [html`
- <div>
- <div x-data x-menu>
- <span>
- <button x-menu:button trigger>
- <span>Options</span>
- </button>
- </span>
- <div x-menu:items items>
- <div>
- <p>Signed in as</p>
- <p>tom@example.com</p>
- </div>
- <div>
- <a x-menu:item href="#account-settings">
- Account settings
- </a>
- <a x-menu:item href="#support">
- Support
- </a>
- <a x-menu:item href="#license">
- License
- </a>
- </div>
- <div>
- <a x-menu:item href="#sign-out">
- Sign out
- </a>
- </div>
- </div>
- </div>
- <button>Focus away</button>
- </div>
- `],
- ({ get }) => {
- get('[items]').should(notBeVisible())
- get('[trigger]').click()
- get('[items]').should(beVisible())
- cy.focused().tab()
- get('[items]').should(notBeVisible())
- },
- )
- test('it works with x-model',
- [html`
- <div x-data="{ open: false }" x-menu x-model="open">
- <button trigger @click="open = !open">
- <span>Options</span>
- </button>
- <button x-menu:button>
- <span>Options</span>
- </button>
- <div x-menu:items items>
- <div>
- <p>Signed in as</p>
- <p>tom@example.com</p>
- </div>
- <div>
- <a x-menu:item href="#account-settings">
- Account settings
- </a>
- <a x-menu:item href="#support">
- Support
- </a>
- <a x-menu:item disabled href="#new-feature">
- New feature (soon)
- </a>
- <a x-menu:item href="#license">
- License
- </a>
- </div>
- <div>
- <a x-menu:item href="#sign-out">
- Sign out
- </a>
- </div>
- </div>
- </div>`],
- ({ get }) => {
- get('[items]').should(notBeVisible())
- get('[trigger]').click()
- get('[items]').should(beVisible())
- get('[trigger]').click()
- get('[items]').should(notBeVisible())
- },
- )
- test('keyboard controls',
- [html`
- <div x-data x-menu>
- <span>
- <button x-menu:button trigger>
- <span>Options</span>
- </button>
- </span>
- <div x-menu:items items>
- <div>
- <p>Signed in as</p>
- <p>tom@example.com</p>
- </div>
- <div>
- <a x-menu:item href="#account-settings" :class="$menuItem.isActive && 'active'">
- Account settings
- </a>
- <a x-menu:item href="#support" :class="$menuItem.isActive && 'active'">
- Support
- </a>
- <a x-menu:item disabled href="#new-feature" :class="$menuItem.isActive && 'active'">
- New feature (soon)
- </a>
- <a x-menu:item href="#license" :class="$menuItem.isActive && 'active'">
- License
- </a>
- </div>
- <div>
- <a x-menu:item href="#sign-out" :class="$menuItem.isActive && 'active'">
- Sign out
- </a>
- </div>
- </div>
- </div>`],
- ({ get }) => {
- get('.active').should(notExist())
- get('[trigger]').type(' ')
- get('[items]')
- .should(beVisible())
- .should(haveFocus())
- .type('{downarrow}')
- get('[href="#account-settings"]')
- .should(haveClasses(['active']))
- get('[items]')
- .type('{downarrow}')
- get('[href="#support"]')
- .should(haveClasses(['active']))
- .type('{downarrow}')
- get('[href="#license"]')
- .should(haveClasses(['active']))
- get('[items]')
- .type('{uparrow}')
- get('[href="#support"]')
- .should(haveClasses(['active']))
- get('[items]')
- .type('{home}')
- get('[href="#account-settings"]')
- .should(haveClasses(['active']))
- get('[items]')
- .type('{end}')
- get('[href="#sign-out"]')
- .should(haveClasses(['active']))
- get('[items]')
- .type('{pageUp}')
- get('[href="#account-settings"]')
- .should(haveClasses(['active']))
- get('[items]')
- .type('{pageDown}')
- get('[href="#sign-out"]')
- .should(haveClasses(['active']))
- get('[items]')
- .tab()
- .should(haveFocus())
- .should(beVisible())
- .tab({ shift: true})
- .should(haveFocus())
- .should(beVisible())
- .type('{esc}')
- .should(notBeVisible())
- },
- )
- test('keyboard controls with x-teleport',
- [html`
- <div x-data x-menu>
- <span>
- <button x-menu:button trigger>
- <span>Options</span>
- </button>
- </span>
- <template x-teleport="body">
- <div x-menu:items items>
- <a x-menu:item href="#account-settings" :class="$menuItem.isActive && 'active'">
- Account settings
- </a>
- <a x-menu:item href="#support" :class="$menuItem.isActive && 'active'">
- Support
- </a>
- </div>
- </template>
- </div>`],
- ({ get }) => {
- get('.active').should(notExist())
- get('[trigger]').type(' ')
- get('[items]')
- .should(beVisible())
- .should(haveFocus())
- .type('{downarrow}')
- get('[href="#account-settings"]')
- .should(haveClasses(['active']))
- get('[items]')
- .type('{downarrow}')
- get('[href="#support"]')
- .should(haveClasses(['active']))
- .type('{uparrow}')
- get('[href="#account-settings"]')
- .should(haveClasses(['active']))
- get('[items]')
- .tab()
- .should(haveFocus())
- .should(beVisible())
- .tab({ shift: true})
- .should(haveFocus())
- .should(beVisible())
- .type('{esc}')
- .should(notBeVisible())
- },
- )
- test('search',
- [html`
- <div x-data x-menu>
- <span>
- <button x-menu:button trigger>
- <span>Options</span>
- </button>
- </span>
- <div x-menu:items items>
- <div>
- <p>Signed in as</p>
- <p>tom@example.com</p>
- </div>
- <div>
- <a x-menu:item href="#account-settings" :class="$menuItem.isActive && 'active'">
- Account settings
- </a>
- <a x-menu:item href="#support" :class="$menuItem.isActive && 'active'">
- Support
- </a>
- <a x-menu:item disabled href="#new-feature" :class="$menuItem.isActive && 'active'">
- New feature (soon)
- </a>
- <a x-menu:item href="#license" :class="$menuItem.isActive && 'active'">
- License
- </a>
- </div>
- <div>
- <a x-menu:item href="#sign-out" :class="$menuItem.isActive && 'active'">
- Sign out
- </a>
- </div>
- </div>
- </div>`],
- ({ get, wait }) => {
- get('.active').should(notExist())
- get('[trigger]').click()
- get('[items]')
- .type('ac')
- get('[href="#account-settings"]')
- .should(haveClasses(['active']))
- wait(500)
- get('[items]')
- .type('si')
- get('[href="#sign-out"]')
- .should(haveClasses(['active']))
- },
- )
- test('has accessibility attributes',
- [html`
- <div x-data x-menu>
- <label x-menu:label>Options label</label>
- <span>
- <button x-menu:button trigger>
- <span>Options</span>
- </button>
- </span>
- <div x-menu:items items>
- <div>
- <p>Signed in as</p>
- <p>tom@example.com</p>
- </div>
- <div>
- <a x-menu:item href="#account-settings" :class="$menuItem.isActive && 'active'">
- Account settings
- </a>
- <a x-menu:item href="#support" :class="$menuItem.isActive && 'active'">
- Support
- </a>
- <a x-menu:item disabled href="#new-feature" :class="$menuItem.isActive && 'active'">
- New feature (soon)
- </a>
- <a x-menu:item href="#license" :class="$menuItem.isActive && 'active'">
- License
- </a>
- </div>
- <div>
- <a x-menu:item href="#sign-out" :class="$menuItem.isActive && 'active'">
- Sign out
- </a>
- </div>
- </div>
- </div>`],
- ({ get }) => {
- get('[trigger]')
- .should(haveAttribute('aria-haspopup', 'true'))
- .should(haveAttribute('aria-labelledby', 'alpine-menu-label-1'))
- .should(haveAttribute('aria-expanded', 'false'))
- .should(notHaveAttribute('aria-controls'))
- .should(haveAttribute('id', 'alpine-menu-button-1'))
- .click()
- .should(haveAttribute('aria-expanded', 'true'))
- .should(haveAttribute('aria-controls', 'alpine-menu-items-1'))
- get('[items]')
- .should(haveAttribute('aria-orientation', 'vertical'))
- .should(haveAttribute('role', 'menu'))
- .should(haveAttribute('id', 'alpine-menu-items-1'))
- .should(haveAttribute('aria-labelledby', 'alpine-menu-button-1'))
- .should(notHaveAttribute('aria-activedescendant'))
- .should(haveAttribute('tabindex', '0'))
- .type('{downarrow}')
- .should(haveAttribute('aria-activedescendant', 'alpine-menu-item-1'))
- get('[href="#account-settings"]')
- .should(haveAttribute('role', 'menuitem'))
- .should(haveAttribute('id', 'alpine-menu-item-1'))
- .should(haveAttribute('tabindex', '-1'))
- get('[href="#support"]')
- .should(haveAttribute('role', 'menuitem'))
- .should(haveAttribute('id', 'alpine-menu-item-2'))
- .should(haveAttribute('tabindex', '-1'))
- get('[items]')
- .type('{downarrow}')
- .should(haveAttribute('aria-activedescendant', 'alpine-menu-item-2'))
- },
- )
- test('$menuItem.isDisabled',
- [html`
- <div x-data x-menu>
- <label x-menu:label>Options label</label>
- <span>
- <button x-menu:button trigger>
- <span>Options</span>
- </button>
- </span>
- <div x-menu:items items>
- <div>
- <p>Signed in as</p>
- <p>tom@example.com</p>
- </div>
- <div>
- <a x-menu:item href="#account-settings" :class="{ 'active': $menuItem.isActive, 'disabled': $menuItem.isDisabled }">
- Account settings
- </a>
- <a x-menu:item href="#support" :class="{ 'active': $menuItem.isActive, 'disabled': $menuItem.isDisabled }">
- Support
- </a>
- <a x-menu:item disabled href="#new-feature" :class="{ 'active': $menuItem.isActive, 'disabled': $menuItem.isDisabled }">
- New feature (soon)
- </a>
- <a x-menu:item href="#license" :class="{ 'active': $menuItem.isActive, 'disabled': $menuItem.isDisabled }">
- License
- </a>
- </div>
- <div>
- <a x-menu:item href="#sign-out" :class="{ 'active': $menuItem.isActive, 'disabled': $menuItem.isDisabled }">
- Sign out
- </a>
- </div>
- </div>
- </div>`],
- ({ get }) => {
- get('[trigger]').click()
- get('[href="#account-settings"]').should(notHaveClasses(['disabled']))
- get('[href="#support"]').should(notHaveClasses(['disabled']))
- get('[href="#new-feature"]').should(haveClasses(['disabled']))
- },
- )
|