diff --git a/packages/editor/gherkin-spec/annotations-collaboration.feature b/packages/editor/gherkin-spec/annotations-collaboration.feature index e0982d89e..6910d0d52 100644 --- a/packages/editor/gherkin-spec/annotations-collaboration.feature +++ b/packages/editor/gherkin-spec/annotations-collaboration.feature @@ -11,8 +11,8 @@ Feature: Annotations Collaboration And the caret is put after "foo" And "{Backspace}" is pressed And Editor B is focused - And the caret is put after "fo" by Editor B - And "a" is typed by Editor B + And the caret is put after "fo" in Editor B + And "a" is typed in Editor B Then the text is "fo,a" And "fo" has marks "c1" And "a" has no marks diff --git a/packages/editor/gherkin-spec/selection.feature b/packages/editor/gherkin-spec/selection.feature index 8dc364cf7..e15aef67c 100644 --- a/packages/editor/gherkin-spec/selection.feature +++ b/packages/editor/gherkin-spec/selection.feature @@ -11,8 +11,6 @@ Feature: Selection And "{Shift>}{ArrowLeft}{/Shift}" is pressed Then "o|" is selected - # Flaky - @skip Scenario: Expanding selection backwards, then forwards Given the text "foo|bar" When the editor is focused diff --git a/packages/editor/gherkin-spec/undo-redo-collaboration.feature b/packages/editor/gherkin-spec/undo-redo-collaboration.feature deleted file mode 100644 index e0178c836..000000000 --- a/packages/editor/gherkin-spec/undo-redo-collaboration.feature +++ /dev/null @@ -1,101 +0,0 @@ -Feature: Undo/Redo Collaboration - - Background: - Given two editors - And a global keymap - - Scenario: Undoing deleting before remote text - Given the text "hello world" - When "Backspace" is pressed - And the caret is put after "hello worl" by editor B - And " there" is typed by editor B - Then the text is "hello worl there" - When undo is performed - Then the text is "hello world there" - - Scenario: Undoing respective changes - Given the text "foo bar baz" - When the caret is put after "foo" - And the caret is put after "bar" by editor B - And "o" is typed - And "o" is typed - And "o" is typed - And "r" is typed by editor B - And "r" is typed by editor B - And "r" is typed by editor B - Then the text is "fooooo barrrr baz" - When undo is performed - Then the text is "foo barrrr baz" - When undo is performed by editor B - Then the text is "foo bar baz" - - Scenario: Undoing respective changes in different blocks - Given the text "foo" in block "b1" - And the text "bar" in block "b2" - When the caret is put after "foo" - And the caret is put after "bar" by editor B - And "o" is typed - And "o" is typed - And "o" is typed - And "r" is typed by editor B - And "r" is typed by editor B - And "r" is typed by editor B - Then the text is "fooooo|barrrr" - When undo is performed - Then the text is "foo|barrrr" - When undo is performed by editor B - Then the text is "foo|bar" - - # Currently fails - @skip - Scenario: Undoing changes after remote block split - Given the text "foo bar" - When the caret is put after "bar" - And " baz" is typed - And the caret is put after "foo" by editor B - And "Enter" is pressed by editor B - And undo is performed - Then the text is "foo| bar" - - @skip - Scenario: Undoing local annotation added before remote annotation - Given the text "foobar" - And a "comment" "c1" around "foo" - And a "link" "l1" around "bar" by editor B - When undo is performed - Then the text is "foo,bar" - And "foo" has no marks - And "bar" has marks "l1" - - Scenario: Undoing local annotation added after remote annotation - Given the text "foobar" - And a "link" "l1" around "bar" by editor B - And a "comment" "c1" around "foo" - When undo is performed - Then the text is "foo,bar" - And "foo" has no marks - And "bar" has marks "l1" - - @skip - Scenario: Undoing local same-type annotation added before remote annotation - Given the text "foobar" - And a "comment" "c1" around "foo" - And a "comment" "c2" around "bar" by editor B - When undo is performed - Then the text is "foo,bar" - And "foo" has no marks - And "bar" has marks "c2" - - # Currently fails - @skip - Scenario: Undoing and redoing local annotation before remote annotation - Given the text "foobar" - And a "comment" "c1" around "foo" - And a "comment" "c2" around "bar" by editor B - When undo is performed - Then the text is "foo,bar" - And "foo" has no marks - And "bar" has marks "c2" - When redo is performed - Then "foo" has marks "c1" - And "bar" has marks "c2" diff --git a/packages/editor/gherkin-spec/undo-redo.feature b/packages/editor/gherkin-spec/undo-redo.feature index fc8845c4c..dbe737bf6 100644 --- a/packages/editor/gherkin-spec/undo-redo.feature +++ b/packages/editor/gherkin-spec/undo-redo.feature @@ -4,6 +4,22 @@ Feature: Undo/Redo Given one editor And a global keymap + Scenario: Undoing writing two words + Given the text "" + When "foo" is typed + And " bar" is typed + And undo is performed + Then the text is "foo" + + Scenario: Selection change does not affect the undo stack + Given the text "" + When "foo" is typed + And "{ArrowLeft}" is pressed + And "bar" is typed + Then the text is "fobaro" + When undo is performed + Then the text is "foo" + Scenario: Undoing annotation Given the text "foo" When "foo" is selected @@ -15,8 +31,8 @@ Feature: Undo/Redo Scenario: Undoing the deletion of the last char of annotated text Given the text "foo" And a "comment" "c1" around "foo" - When "ArrowRight" is pressed - And "Backspace" is pressed + When "{ArrowRight}" is pressed + And "{Backspace}" is pressed And undo is performed Then the text is "foo" And "foo" has marks "c1" @@ -24,8 +40,8 @@ Feature: Undo/Redo Scenario: Redoing the deletion of the last char of annotated text Given the text "foo" And a "comment" "c1" around "foo" - When "ArrowRight" is pressed - And "Backspace" is pressed + When "{ArrowRight}" is pressed + And "{Backspace}" is pressed And undo is performed When redo is performed Then the text is "fo" @@ -34,8 +50,8 @@ Feature: Undo/Redo Scenario: Undoing inserting text after annotated text Given the text "foo" And a "comment" "c1" around "foo" - When "ArrowRight" is pressed - And "Space" is pressed + When "{ArrowRight}" is pressed + And "{Space}" is pressed Then the text is "foo, " And "foo" has marks "c1" And " " has no marks @@ -46,8 +62,8 @@ Feature: Undo/Redo Scenario: Undoing and redoing inserting text after annotated text Given the text "foo" And a "comment" "c1" around "foo" - When "ArrowRight" is pressed - And "Space" is pressed + When "{ArrowRight}" is pressed + And "{Space}" is pressed And undo is performed Then the text is "foo" And "foo" has marks "c1" @@ -60,7 +76,7 @@ Feature: Undo/Redo Given the text "foo bar" And a "comment" "c1" around "bar" When "foo bar" is selected - And "Backspace" is pressed + And "{Backspace}" is pressed And undo is performed Then the text is "foo ,bar" And "bar" has marks "c1" @@ -68,14 +84,14 @@ Feature: Undo/Redo Scenario: Undoing deletion of annotated block Given the text "foo" And a "comment" "c1" around "foo" - When "Backspace" is pressed + When "{Backspace}" is pressed And undo is performed Then the text is "foo" And "foo" has marks "c1" Scenario: Undoing annotation across text blocks Given the text "foo" - When "Enter" is pressed + When "{Enter}" is pressed And "bar" is typed And "foobar" is selected And "link" is toggled diff --git a/packages/editor/gherkin-tests-v2/undo-redo.test.ts b/packages/editor/gherkin-tests-v2/undo-redo.test.ts new file mode 100644 index 000000000..aa41a9d86 --- /dev/null +++ b/packages/editor/gherkin-tests-v2/undo-redo.test.ts @@ -0,0 +1,10 @@ +import {Feature} from 'racejar/vitest' +import undoRedoFeature from '../gherkin-spec/undo-redo.feature?raw' +import {parameterTypes} from '../src/test' +import {stepDefinitions} from '../src/test/vitest' + +Feature({ + featureText: undoRedoFeature, + stepDefinitions, + parameterTypes, +}) diff --git a/packages/editor/gherkin-tests/undo-redo.test.ts b/packages/editor/gherkin-tests/undo-redo.test.ts deleted file mode 100644 index 2c8bf58c8..000000000 --- a/packages/editor/gherkin-tests/undo-redo.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {Feature} from 'racejar/vitest' -import undoRedoCollaborationFeature from '../gherkin-spec/undo-redo-collaboration.feature?raw' -import undoRedoFeature from '../gherkin-spec/undo-redo.feature?raw' -import {parameterTypes} from './gherkin-parameter-types' -import {stepDefinitions} from './gherkin-step-definitions' - -Feature({ - featureText: undoRedoFeature, - stepDefinitions, - parameterTypes, -}) - -Feature({ - featureText: undoRedoCollaborationFeature, - stepDefinitions, - parameterTypes, -}) diff --git a/packages/editor/src/test/vitest/step-definitions.tsx b/packages/editor/src/test/vitest/step-definitions.tsx index 8c87ebced..0ef5a4a99 100644 --- a/packages/editor/src/test/vitest/step-definitions.tsx +++ b/packages/editor/src/test/vitest/step-definitions.tsx @@ -190,7 +190,7 @@ export const stepDefinitions = [ await userEvent.type(context.locator, text) }), When( - '{string} is typed by Editor B', + '{string} is typed in Editor B', async (context: Context, text: string) => { await userEvent.type(context.locatorB, text) }, @@ -222,23 +222,40 @@ export const stepDefinitions = [ */ When( '{button} is pressed', - async (_: Context, button: Parameter['button']) => { + async (context: Context, button: Parameter['button']) => { + const previousSelection = context.editor.getSnapshot().context.selection await userEvent.keyboard(button) - await new Promise((resolve) => setTimeout(resolve, 100)) + + await vi.waitFor(() => { + const currentSelection = context.editor.getSnapshot().context.selection + + if (currentSelection) { + expect(currentSelection).not.toBe(previousSelection) + } + }) }, ), When( '{button} is pressed {int} times', - async (_: Context, button: Parameter['button'], times: number) => { + async (context: Context, button: Parameter['button'], times: number) => { for (let i = 0; i < times; i++) { + const previousSelection = context.editor.getSnapshot().context.selection await userEvent.keyboard(button) - await new Promise((resolve) => setTimeout(resolve, 100)) + + await vi.waitFor(() => { + const currentSelection = + context.editor.getSnapshot().context.selection + + if (currentSelection) { + expect(currentSelection).not.toBe(previousSelection) + } + }) } }, ), When( '{shortcut} is pressed', - async (_: Context, shortcut: Parameter['shortcut']) => { + async (context: Context, shortcut: Parameter['shortcut']) => { const shortcuts: Record = { 'deleteWord.backward': IS_MAC ? '{Alt>}{Backspace}{/Alt}' @@ -248,8 +265,16 @@ export const stepDefinitions = [ : '{Control>}{Delete}{/Control}', } + const previousSelection = context.editor.getSnapshot().context.selection await userEvent.keyboard(shortcuts[shortcut]) - await new Promise((resolve) => setTimeout(resolve, 100)) + + await vi.waitFor(() => { + const currentSelection = context.editor.getSnapshot().context.selection + + if (currentSelection) { + expect(currentSelection).not.toBe(previousSelection) + } + }) }, ), @@ -315,7 +340,7 @@ export const stepDefinitions = [ }, ), When( - 'the caret is put after {string} by Editor B', + 'the caret is put after {string} in Editor B', async (context: Context, text: string) => { await vi.waitFor(() => { const selection = getSelectionAfterText( diff --git a/packages/editor/tests/event.history.undo.test.tsx b/packages/editor/tests/event.history.undo.test.tsx index d8a188b0b..1cd376238 100644 --- a/packages/editor/tests/event.history.undo.test.tsx +++ b/packages/editor/tests/event.history.undo.test.tsx @@ -5,67 +5,11 @@ import {userEvent} from 'vitest/browser' import type {EditorSelection} from '../src' import {execute, forward, raise} from '../src/behaviors/behavior.types.action' import {defineBehavior} from '../src/behaviors/behavior.types.behavior' -import type {MutationEvent} from '../src/editor/relay-machine' import {BehaviorPlugin} from '../src/plugins/plugin.behavior' -import {EventListenerPlugin} from '../src/plugins/plugin.event-listener' import {getFirstBlock, getFocusBlock} from '../src/selectors' import {createTestEditor} from '../src/test/vitest' describe('event.history.undo', () => { - test('Scenario: Undoing writing two words', async () => { - const mutationEvents: Array = [] - - const {editor, locator} = await createTestEditor({ - children: ( - { - if (event.type === 'mutation') { - mutationEvents.push(event) - } - }} - /> - ), - }) - - await userEvent.type(locator, 'foo') - await userEvent.type(locator, ' bar') - - await vi.waitFor(() => { - expect(getTersePt(editor.getSnapshot().context)).toEqual(['foo bar']) - }) - - editor.send({type: 'history.undo'}) - - await vi.waitFor(() => { - expect(getTersePt(editor.getSnapshot().context)).toEqual(['foo']) - }) - }) - - test('Scenario: Selection change does not affect the undo stack', async () => { - const {editor, locator} = await createTestEditor() - - await userEvent.click(locator) - await userEvent.type(locator, 'foo') - await userEvent.keyboard('{ArrowLeft}') - await userEvent.type(locator, 'bar') - - await vi.waitFor(() => { - expect(getTersePt(editor.getSnapshot().context)).toEqual(['fobaro']) - }) - - editor.send({type: 'history.undo'}) - - await vi.waitFor(() => { - expect(getTersePt(editor.getSnapshot().context)).toEqual(['foo']) - }) - - editor.send({type: 'history.undo'}) - - await vi.waitFor(() => { - expect(getTersePt(editor.getSnapshot().context)).toEqual(['']) - }) - }) - test('Scenario: Undoing action sets', async () => { const {editor, locator} = await createTestEditor({ children: (