diff --git a/src/editor/customMarkdownConverter.test.ts b/src/editor/customMarkdownConverter.test.ts index 43bb89d..88570d2 100644 --- a/src/editor/customMarkdownConverter.test.ts +++ b/src/editor/customMarkdownConverter.test.ts @@ -1008,6 +1008,24 @@ describe("markdownToBlocks", () => { expect(nestedChildren.some((child) => child.type === "bulletListItem")).toBe(true); }); + it("does not freeze on indented list items without a parent", () => { + const markdown = [ + "### Requirements", + "", + " * The system should log in the user {{username}} with password ${password} successfully.", + "", + " ### Steps", + "", + " * Open login page", + " *Expected*: The main page is opened", + ].join("\n"); + + const blocks = markdownToBlocks(markdown); + expect(blocks.length).toBeGreaterThan(0); + const bullets = blocks.filter((b) => b.type === "bulletListItem"); + expect(bullets.length).toBeGreaterThanOrEqual(1); + }); + it("parses expected result prefixes with emphasis", () => { const markdown = [ "* Open the form.", diff --git a/src/editor/customMarkdownConverter.ts b/src/editor/customMarkdownConverter.ts index 1a9312c..187d0c4 100644 --- a/src/editor/customMarkdownConverter.ts +++ b/src/editor/customMarkdownConverter.ts @@ -796,7 +796,7 @@ function parseList( // Check if this line should be parsed as nested content // Only go deeper if indent is at least 2 more than the next level's expected indent const nextLevelExpectedIndent = (indentLevel + 1) * 2; - if (indent >= nextLevelExpectedIndent) { + if (indent >= nextLevelExpectedIndent && items.length > 0) { const lastItem = items.at(-1); if (!lastItem) { break; diff --git a/src/editor/snippetAutocomplete.ts b/src/editor/snippetAutocomplete.ts index 3a0cf61..0f501bf 100644 --- a/src/editor/snippetAutocomplete.ts +++ b/src/editor/snippetAutocomplete.ts @@ -45,14 +45,13 @@ export function useSnippetAutocomplete(): SnippetSuggestion[] { const [suggestions, setSuggestions] = useState(() => { if (cachedSuggestions.length > 0) return cachedSuggestions; if (!globalFetcher) return []; + if (inflightPromise) return []; const result = globalFetcher(); if (result && typeof (result as Promise).then === "function") { - if (!inflightPromise) { - inflightPromise = (result as Promise) - .then((r) => normalizeSnippetSuggestions(r)) - .then((items) => { cachedSuggestions = items; inflightPromise = null; return items; }) - .catch((error) => { inflightPromise = null; console.error("Failed to fetch snippet suggestions", error); return [] as SnippetSuggestion[]; }); - } + inflightPromise = (result as Promise) + .then((r) => normalizeSnippetSuggestions(r)) + .then((items) => { cachedSuggestions = items; inflightPromise = null; return items; }) + .catch((error) => { inflightPromise = null; console.error("Failed to fetch snippet suggestions", error); return [] as SnippetSuggestion[]; }); return []; } const normalized = normalizeSnippetSuggestions(result as SnippetInput); diff --git a/src/editor/stepAutocomplete.tsx b/src/editor/stepAutocomplete.tsx index e96642e..53f6288 100644 --- a/src/editor/stepAutocomplete.tsx +++ b/src/editor/stepAutocomplete.tsx @@ -51,14 +51,13 @@ export function useStepAutocomplete(): StepSuggestion[] { const [suggestions, setSuggestions] = useState(() => { if (cachedSuggestions.length > 0) return cachedSuggestions; if (!globalFetcher) return []; + if (inflightPromise) return []; const result = globalFetcher(); if (result && typeof (result as Promise).then === "function") { - if (!inflightPromise) { - inflightPromise = (result as Promise) - .then((r) => normalizeStepSuggestions(r)) - .then((items) => { cachedSuggestions = items; inflightPromise = null; return items; }) - .catch((error) => { inflightPromise = null; console.error("Failed to fetch step suggestions", error); return [] as StepSuggestion[]; }); - } + inflightPromise = (result as Promise) + .then((r) => normalizeStepSuggestions(r)) + .then((items) => { cachedSuggestions = items; inflightPromise = null; return items; }) + .catch((error) => { inflightPromise = null; console.error("Failed to fetch step suggestions", error); return [] as StepSuggestion[]; }); return []; } const normalized = normalizeStepSuggestions(result as StepInput);