-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Vitest: use browser mode #3222
Vitest: use browser mode #3222
Changes from all commits
da82cf2
a7544ef
8e45bf7
0674e45
d017dc5
688da4a
f89eab6
120dbe8
3dfd6be
6f2dc5f
fcb3529
c139439
d837de5
58949a5
3ac17b6
0a9f928
0e01ae7
32d0b83
6bec38a
1fce59e
e9f15c1
3ff5006
1b01229
94c3590
6e3d074
771fdd5
958bf48
fb09afc
180f036
1414131
a105d62
959952c
6723185
ac78ceb
f32859d
c283352
9518004
3addf3f
8b24692
776b054
21e11d7
d3f07b7
b2544ff
25bcfc2
bf428fa
2721a21
2e2bd95
4cef86b
6202567
641cee0
956652d
26c206b
a413b7f
677bc29
c98497a
3e22579
9413d50
75687c4
5fee759
8be6552
3e8cbfb
84b8070
6fa2e78
3f1e40e
544dbfe
081cb12
b110135
c6eaa27
0204627
9a21141
5e56d36
3d33aea
31e4756
48335e4
e9224b8
315caed
e796eeb
8ec5203
8035aa6
dc7b690
51b1f30
0e17bfc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,41 @@ | ||
import { fireEvent } from '@testing-library/react'; | ||
import { act } from 'react'; | ||
import { commands, userEvent } from '@vitest/browser/context'; | ||
|
||
import type { Column } from '../../src'; | ||
import { resizeHandleClassname } from '../../src/HeaderCell'; | ||
import { getGrid, getHeaderCells, setup } from '../utils'; | ||
|
||
const pointerId = 1; | ||
|
||
// TODO: https://github.com/jsdom/jsdom/issues/2527 | ||
class PointerEvent extends Event { | ||
pointerId: number | undefined; | ||
clientX: number | undefined; | ||
interface Row { | ||
readonly col1: number; | ||
readonly col2: string; | ||
} | ||
|
||
constructor(type: string, { pointerId, clientX, ...rest }: PointerEventInit) { | ||
super(type, rest); | ||
this.pointerId = pointerId; | ||
this.clientX = clientX; | ||
} | ||
interface ResizeArgs { | ||
readonly column: HTMLElement; | ||
readonly resizeBy: number; | ||
} | ||
|
||
// @ts-expect-error | ||
globalThis.PointerEvent = PointerEvent; | ||
async function resize({ column, resizeBy }: ResizeArgs) { | ||
const resizeHandle = column.querySelector(`.${resizeHandleClassname}`); | ||
if (resizeHandle === null) return; | ||
|
||
interface ResizeEvent<K extends keyof DOMRect> { | ||
column: HTMLElement; | ||
clientXStart: number; | ||
clientXEnd: number; | ||
rect: Pick<DOMRect, K>; | ||
await act(async () => { | ||
// @ts-expect-error | ||
await commands.resizeColumn(resizeBy); | ||
}); | ||
} | ||
|
||
function resize<K extends keyof DOMRect>({ | ||
column, | ||
clientXStart, | ||
clientXEnd, | ||
rect | ||
}: ResizeEvent<K>) { | ||
async function autoResize(column: HTMLElement) { | ||
const resizeHandle = column.querySelector(`.${resizeHandleClassname}`); | ||
if (resizeHandle === null) return; | ||
|
||
const original = column.getBoundingClientRect.bind(column); | ||
column.getBoundingClientRect = () => ({ | ||
...original(), | ||
...rect | ||
// eslint-disable-next-line testing-library/no-unnecessary-act | ||
await act(async () => { | ||
await userEvent.dblClick(resizeHandle); | ||
}); | ||
// eslint-disable-next-line testing-library/prefer-user-event | ||
fireEvent.pointerDown( | ||
resizeHandle, | ||
new PointerEvent('pointerdown', { pointerId, clientX: clientXStart }) | ||
); | ||
// eslint-disable-next-line testing-library/prefer-user-event | ||
fireEvent.pointerMove(resizeHandle, new PointerEvent('pointermove', { clientX: clientXEnd })); | ||
fireEvent.lostPointerCapture(resizeHandle, new PointerEvent('lostpointercapture', {})); | ||
} | ||
|
||
const columns: readonly Column<never>[] = [ | ||
const columns: readonly Column<Row>[] = [ | ||
{ | ||
key: 'col1', | ||
name: 'col1', | ||
|
@@ -68,34 +51,85 @@ const columns: readonly Column<never>[] = [ | |
} | ||
]; | ||
|
||
test('should not resize column if resizable is not specified', () => { | ||
setup({ columns, rows: [] }); | ||
test('should not resize column if resizable is not specified', async () => { | ||
setup<Row, unknown>({ columns, rows: [] }); | ||
const [col1] = getHeaderCells(); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); | ||
resize({ column: col1, clientXStart: 95, clientXEnd: 200, rect: { right: 100, left: 0 } }); | ||
await resize({ column: col1, resizeBy: 50 }); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); | ||
await resize({ column: col1, resizeBy: -50 }); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); | ||
}); | ||
|
||
test('should resize column when dragging the handle', () => { | ||
setup({ columns, rows: [] }); | ||
test('should resize column when dragging the handle', async () => { | ||
setup<Row, unknown>({ columns, rows: [] }); | ||
const [, col2] = getHeaderCells(); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); | ||
resize({ column: col2, clientXStart: 289, clientXEnd: 250, rect: { right: 300, left: 100 } }); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 161px' }); | ||
const grid = getGrid(); | ||
expect(grid).toHaveStyle({ gridTemplateColumns: '100px 200px' }); | ||
await resize({ column: col2, resizeBy: -50 }); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 150px' }); | ||
}); | ||
|
||
test('should use the maxWidth if specified', () => { | ||
setup({ columns, rows: [] }); | ||
test('should use the maxWidth if specified', async () => { | ||
setup<Row, unknown>({ columns, rows: [] }); | ||
const [, col2] = getHeaderCells(); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); | ||
resize({ column: col2, clientXStart: 295, clientXEnd: 1000, rect: { right: 300, left: 100 } }); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px ' }); | ||
await resize({ column: col2, resizeBy: 1000 }); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 400px' }); | ||
}); | ||
|
||
test('should use the minWidth if specified', () => { | ||
setup({ columns, rows: [] }); | ||
test('should use the minWidth if specified', async () => { | ||
setup<Row, unknown>({ columns, rows: [] }); | ||
const [, col2] = getHeaderCells(); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); | ||
resize({ column: col2, clientXStart: 295, clientXEnd: 100, rect: { right: 300, left: 100 } }); | ||
await resize({ column: col2, resizeBy: -150 }); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 100px' }); | ||
}); | ||
|
||
test('should not auto resize column if resizable is not specified', async () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now we can test auto column |
||
setup<Row, unknown>({ | ||
columns, | ||
rows: [ | ||
{ | ||
col1: 1, | ||
col2: 'a'.repeat(50) | ||
} | ||
] | ||
}); | ||
const [col1] = getHeaderCells(); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); | ||
await autoResize(col1); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); | ||
}); | ||
|
||
test('should auto resize column when resize handle is double clicked', async () => { | ||
setup<Row, unknown>({ | ||
columns, | ||
rows: [ | ||
{ | ||
col1: 1, | ||
col2: 'a'.repeat(50) | ||
} | ||
] | ||
}); | ||
const [, col2] = getHeaderCells(); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); | ||
await autoResize(col2); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 327.703px' }); | ||
}); | ||
|
||
test('should use the maxWidth if specified on auto resize', async () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could also test minWidth There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will add it in the nest PR |
||
setup<Row, unknown>({ | ||
columns, | ||
rows: [ | ||
{ | ||
col1: 1, | ||
col2: 'a'.repeat(500) | ||
} | ||
] | ||
}); | ||
const [, col2] = getHeaderCells(); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 200px' }); | ||
await autoResize(col2); | ||
expect(getGrid()).toHaveStyle({ gridTemplateColumns: '100px 400px' }); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did we remove these checks?
this checked that when typing on a cell, it opens the editor and the editor receives focus, and we continue typing in the editor
this checked that we scrolled back to the cell even if we had scrolled past it (see
await scrollGrid({ scrollTop: 2000 });
above)Maybe we need more comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to check the actual row in the view instead of spying on
scrollIntoView