Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(ui-tray): migrate old Tray tests #1844

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,49 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import React from 'react'
import { Tray } from '@instructure/ui'

import { locator } from '@instructure/ui-test-locator'
import '../support/component'
import 'cypress-real-events'

import { Tray } from './index'
describe('<Tray />', () => {
it('should apply theme overrides when open', async () => {
cy.mount(
<Tray
label="Tray Example"
open
size="small"
placement="start"
themeOverride={{ smallWidth: '10em' }}
>
<div>Hello</div>
</Tray>
)

// @ts-expect-error ts-migrate(2339) FIXME: Property 'selector' does not exist on type 'typeof... Remove this comment to see the full error message
export const TrayLocator = locator(Tray.selector)
cy.get('[aria-label="Tray Example"]')
.should('have.attr', 'role', 'dialog')
.and('have.css', 'width', '160px')
})

it('should call onDismiss prop when Esc key pressed', async () => {
const onDismiss = cy.stub()
cy.mount(
<Tray
open
label="Tray Example"
shouldCloseOnDocumentClick
onDismiss={onDismiss}
>
Hello Tray
<input type="text" />
<input type="text" id="my-input" />
</Tray>
)

cy.get('[aria-label="Tray Example"]').as('tray')

cy.get('@tray').realPress('Escape')
Copy link
Contributor

@ToMESSKa ToMESSKa Jan 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original test has a focus check on the tray before pressing the Esc key, which I don't see here.

cy.wrap(onDismiss).should('have.been.called')
})
})
8 changes: 5 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions packages/ui-tray/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@
},
"devDependencies": {
"@instructure/ui-babel-preset": "10.10.0",
"@instructure/ui-test-locator": "10.10.0",
"@instructure/ui-test-utils": "10.10.0",
"@instructure/ui-themes": "10.10.0"
"@instructure/ui-themes": "10.10.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.0.1",
"@testing-library/user-event": "^14.5.2",
"vitest": "^2.1.8"
},
"peerDependencies": {
"react": ">=16.14 <=18"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,151 +23,93 @@
*/

import React from 'react'

import {
expect,
mount,
stub,
wait,
wrapQueryResult
} from '@instructure/ui-test-utils'
import { render, screen, waitFor } from '@testing-library/react'
import { vi } from 'vitest'
import '@testing-library/jest-dom'

import { Tray } from '../index'
import { TrayLocator } from '../TrayLocator'
import type { TrayProps } from '../props'

describe('<Tray />', async () => {
it('should render nothing and have a node with no parent when closed', async () => {
await mount(<Tray label="Tray Example">Hello World</Tray>)
const tray = await TrayLocator.find({ expectEmpty: true })
expect(tray).to.not.exist()
render(<Tray label="Tray Example">Hello Tray</Tray>)

const trayContent = screen.queryByText('Hello Tray')
expect(trayContent).not.toBeInTheDocument()
})

it('should render children and have a node with a parent when open', async () => {
await mount(
render(
<Tray label="Tray Example" open>
Hello World
Hello Tray
</Tray>
)
const trayContent = screen.getByText('Hello Tray')

const tray = await TrayLocator.find(':label(Tray Example)')
await wait(() => expect(tray.getTextContent()).to.equal('Hello World'))
})

it('should apply theme overrides when open', async () => {
await mount(
<Tray
label="Tray Example"
open
size="small"
placement="start"
themeOverride={{ smallWidth: '10em' }}
>
<div>Hello</div>
</Tray>
)
const tray = await TrayLocator.find()
const dialog = await tray.find('[role="dialog"]')
await wait(() => {
expect(dialog.getComputedStyle().width).to.equal('160px')
})
expect(trayContent).toBeInTheDocument()
})

it('should apply the a11y attributes', async () => {
await mount(
render(
<Tray label="Tray Example" open>
Hello World
Hello Tray
</Tray>
)
const tray = await TrayLocator.find()
const dialog = await tray.find('[role="dialog"]')
const tray = screen.getByRole('dialog')

expect(dialog.getAttribute('aria-label')).to.equal('Tray Example')
expect(tray).toHaveAttribute('aria-label', 'Tray Example')
})

it('should support onOpen prop', async () => {
const onOpen = stub()
await mount(
const onOpen = vi.fn()
render(
<Tray label="Tray Example" open onOpen={onOpen}>
Hello World
Hello Tray
</Tray>
)

await wait(() => {
expect(onOpen).to.have.been.called()
await waitFor(() => {
expect(onOpen).toHaveBeenCalled()
})
})

it('should support onClose prop', async () => {
const onClose = stub()
const onClose = vi.fn()

const subject = await mount(
const { rerender } = render(
<Tray label="Tray Example" open onClose={onClose}>
Hello World
Hello Tray
</Tray>
)

await subject.setProps({ open: false })
// Set prop: open
rerender(
<Tray label="Tray Example" open={false} onClose={onClose}>
Hello Tray
</Tray>
)

await wait(() => {
expect(onClose).to.have.been.called()
await waitFor(() => {
expect(onClose).toHaveBeenCalled()
})
})

it('should take a prop for finding default focus', async () => {
await mount(
render(
<Tray
label="Tray Example"
open
defaultFocusElement={() => document.getElementById('my-input')}
>
Hello World
Hello Tray
<input type="text" />
<input type="text" id="my-input" />
<input type="text" id="my-input" aria-label="my-input-label" />
</Tray>
)
const input = screen.getByLabelText('my-input-label')

const tray = await TrayLocator.find()
const input = await tray.find('#my-input')

await wait(() => {
expect(input.focused()).to.be.true()
})
})

it('should call onDismiss prop when Esc key pressed', async () => {
const onDismiss = stub()
await mount(
<Tray
open
label="Tray Example"
shouldCloseOnDocumentClick
onDismiss={onDismiss}
>
Hello World
<input type="text" />
<input type="text" id="my-input" />
</Tray>
)

const tray = await TrayLocator.find()

await wait(() => {
expect(tray.containsFocus()).to.be.true()
})

await wrapQueryResult(tray.getOwnerDocument().documentElement).keyUp(
'escape',
{
defaultPrevented: false,
bubbles: true,
button: 0
},
{ focusable: false }
)

await wait(() => {
expect(onDismiss).to.have.been.called()
await waitFor(() => {
expect(document.activeElement).toBe(input)
})
})

Expand Down Expand Up @@ -204,10 +146,10 @@ describe('<Tray />', async () => {
for (const placement in placements[dir].enteringPlacements) {
const val = placements[dir].enteringPlacements[placement]
it(`returns ${val} for ${placement} when entering`, async () => {
const onEntered = stub()
const onEntered = vi.fn()
document.documentElement.setAttribute('dir', dir)

await mount(
render(
<Tray
open
label="Tray Example"
Expand All @@ -217,20 +159,19 @@ describe('<Tray />', async () => {
Hello
</Tray>
)

await wait(() => {
expect(onEntered).to.have.been.called()
await waitFor(() => {
expect(onEntered).toHaveBeenCalled()
})
})
}

for (const placement in placements[dir].exitingPlacements) {
const val = placements[dir].exitingPlacements[placement]
it(`returns ${val} for ${placement} when exiting`, async () => {
const onExited = stub()
const onExited = vi.fn()
document.documentElement.setAttribute('dir', dir)

const subject = await mount(
const { rerender } = render(
<Tray
open
label="Tray Example"
Expand All @@ -241,10 +182,19 @@ describe('<Tray />', async () => {
</Tray>
)

await subject.setProps({ open: false })

await wait(() => {
expect(onExited).to.have.been.called()
// Set prop: open
rerender(
<Tray
open={false}
label="Tray Example"
placement={placement as TrayProps['placement']}
onExited={onExited}
>
Hello
</Tray>
)
await waitFor(() => {
expect(onExited).toHaveBeenCalled()
})
})
}
Expand Down
28 changes: 0 additions & 28 deletions packages/ui-tray/src/Tray/locator.ts

This file was deleted.

2 changes: 0 additions & 2 deletions packages/ui-tray/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
{ "path": "../ui-overlays/tsconfig.build.json" },
{ "path": "../ui-utils/tsconfig.build.json" },
{ "path": "../ui-babel-preset/tsconfig.build.json" },
{ "path": "../ui-test-locator/tsconfig.build.json" },
{ "path": "../ui-test-utils/tsconfig.build.json" },
{ "path": "../ui-themes/tsconfig.build.json" }
]
}
Loading