-
Notifications
You must be signed in to change notification settings - Fork 431
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(playwright-ct): add range decoration test for PT-input
- Loading branch information
1 parent
8a41030
commit af4a95e
Showing
2 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
65 changes: 65 additions & 0 deletions
65
packages/sanity/playwright-ct/tests/formBuilder/inputs/PortableText/RangeDecoration.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import {expect, test} from '@playwright/experimental-ct-react' | ||
import {type SanityDocument} from 'sanity' | ||
|
||
import {testHelpers} from '../../../utils/testHelpers' | ||
import {type DecorationData, RangeDecorationStory} from './RangeDecorationStory' | ||
|
||
const document: SanityDocument = { | ||
_id: '123', | ||
_type: 'test', | ||
_createdAt: new Date().toISOString(), | ||
_updatedAt: new Date().toISOString(), | ||
_rev: '123', | ||
body: [ | ||
{ | ||
_type: 'block', | ||
_key: 'a', | ||
children: [{_type: 'span', _key: 'a1', text: 'Hello there world'}], | ||
markDefs: [], | ||
}, | ||
{ | ||
_type: 'block', | ||
_key: 'b', | ||
children: [{_type: 'span', _key: 'b1', text: "It's a beautiful day on planet earth"}], | ||
markDefs: [], | ||
}, | ||
], | ||
} | ||
|
||
// Since we can't pass React components to our story, we'll just pass the selection data, | ||
// and use a test component inside the Story to render the range decoration. | ||
const decorationData: DecorationData[] = [ | ||
{ | ||
word: 'there', | ||
selection: { | ||
anchor: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 6}, | ||
focus: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 11}, | ||
}, | ||
}, | ||
] | ||
|
||
test.describe('Portable Text Input', () => { | ||
test.describe('Range Decoration', () => { | ||
// test.only('Manual testing can be performed with this test', async ({mount, page}) => { | ||
// await mount(<RangeDecorationStory document={document} decorationData={decorationData} />) | ||
// await page.waitForTimeout(360000) | ||
// }) | ||
test(`Draws range decoration around our selection`, async ({mount, page}) => { | ||
await mount(<RangeDecorationStory document={document} decorationData={decorationData} />) | ||
await expect(page.getByTestId('range-decoration')).toHaveText('there') | ||
}) | ||
|
||
test(`Let's us move the range according to our edits`, async ({mount, page}) => { | ||
const {getFocusedPortableTextEditor, insertPortableText} = testHelpers({page}) | ||
|
||
await mount(<RangeDecorationStory document={document} decorationData={decorationData} />) | ||
|
||
const $pte = await getFocusedPortableTextEditor('field-body') | ||
|
||
await insertPortableText('123 ', $pte) | ||
await expect($pte).toHaveText("123 Hello there worldIt's a beautiful day on planet earth") | ||
// Assert that the same word is decorated after the edit | ||
await expect(page.getByTestId('range-decoration')).toHaveText('there') | ||
}) | ||
}) | ||
}) |
91 changes: 91 additions & 0 deletions
91
packages/sanity/playwright-ct/tests/formBuilder/inputs/PortableText/RangeDecorationStory.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* eslint-disable max-nested-callbacks */ | ||
import {type EditorSelection, type RangeDecoration} from '@sanity/portable-text-editor' | ||
import {defineArrayMember, defineField, defineType, type SanityDocument} from '@sanity/types' | ||
import {type PropsWithChildren, useEffect, useMemo, useState} from 'react' | ||
import {type InputProps, PortableTextInput, type PortableTextInputProps} from 'sanity' | ||
|
||
import {TestForm} from '../../utils/TestForm' | ||
import {TestWrapper} from '../../utils/TestWrapper' | ||
|
||
export type DecorationData = {selection: EditorSelection; word: string} | ||
|
||
const RangeDecorationTestComponent = (props: PropsWithChildren) => { | ||
return ( | ||
<span style={{backgroundColor: 'yellow'}} data-testid="range-decoration"> | ||
{props.children} | ||
</span> | ||
) | ||
} | ||
|
||
const CustomPortableTextInput = ( | ||
props: PortableTextInputProps & {decorationData?: DecorationData[]}, | ||
) => { | ||
const {decorationData} = props | ||
const [rangeDecorationsState, setRangeDecorationsState] = useState<RangeDecoration[]>([]) | ||
|
||
useEffect(() => { | ||
setRangeDecorationsState( | ||
(decorationData?.map((data) => ({ | ||
component: RangeDecorationTestComponent, | ||
selection: data.selection, | ||
onMoved: (movedProps) => { | ||
const {newSelection, rangeDecoration} = movedProps | ||
setRangeDecorationsState((prev) => | ||
prev.map((decoration) => | ||
data.selection === rangeDecoration.selection | ||
? {...decoration, selection: newSelection} | ||
: decoration, | ||
), | ||
) | ||
}, | ||
payload: {word: data.word}, | ||
})) || []) as RangeDecoration[], | ||
) | ||
}, [decorationData]) | ||
|
||
return <PortableTextInput {...props} rangeDecorations={rangeDecorationsState} /> | ||
} | ||
|
||
export function RangeDecorationStory({ | ||
document, | ||
decorationData, | ||
}: { | ||
document?: SanityDocument | ||
decorationData?: DecorationData[] | ||
}) { | ||
const schemaTypes = useMemo( | ||
() => [ | ||
defineType({ | ||
type: 'document', | ||
name: 'test', | ||
title: 'Test', | ||
fields: [ | ||
defineField({ | ||
type: 'array', | ||
name: 'body', | ||
of: [ | ||
defineArrayMember({ | ||
type: 'block', | ||
}), | ||
], | ||
components: { | ||
input: (props: InputProps) => ( | ||
<CustomPortableTextInput | ||
{...(props as PortableTextInputProps)} | ||
decorationData={decorationData} | ||
/> | ||
), | ||
}, | ||
}), | ||
], | ||
}), | ||
], | ||
[decorationData], | ||
) | ||
|
||
return ( | ||
<TestWrapper schemaTypes={schemaTypes}> | ||
<TestForm document={document} /> | ||
</TestWrapper> | ||
) | ||
} |