From c94c3304edc5678769320f0602a9e24856ee0d9d Mon Sep 17 00:00:00 2001 From: Salmen Hichri Date: Sun, 12 May 2024 22:22:03 +0100 Subject: [PATCH] Added waitForReactRenderCycle and fixed specs warnings --- .../StreamContainer/StreamContainerComp.tsx | 4 +- .../react/extras-conversationHistory.spec.tsx | 24 ++++--- .../react/extras-personaOptions.spec.tsx | 29 ++++---- .../behavior/react/exceptionsBox.spec.tsx | 6 +- .../behavior/react/markdown-fetch.spec.tsx | 10 +-- .../behavior/react/markdown-stream.spec.tsx | 23 ++++--- .../react/submitPrompt-fetch.spec.tsx | 52 +++++++------- .../react/submitPrompt-stream.spec.tsx | 69 +++++++++---------- .../behavior/react/welcomeMessage.spec.tsx | 4 +- .../aiChat/options/react/className.spec.tsx | 10 +-- .../conversationOptions-autoScroll.spec.tsx | 18 ++--- .../react/initialConversation.spec.tsx | 14 ++-- .../react/layoutOptions-width.spec.tsx | 28 ++++---- ...messageOptions-markdownLinkTarget.spec.tsx | 36 +++++----- .../messageOptions-responseComponent.spec.tsx | 43 +++++++----- ...geOptions-showCodeBlockCopyButton.spec.tsx | 21 +++--- .../messageOptions-syntaxHighlighter.spec.tsx | 22 +++--- .../options/react/personaOptions-bot.spec.tsx | 46 ++++++------- .../react/personaOptions-user.spec.tsx | 34 ++++----- .../react/promptBoxOptions-autoFocus.spec.tsx | 18 ++--- .../aiChat/options/react/themeId.spec.tsx | 8 +-- .../react/01-create-context.spec.tsx | 38 +++++----- .../react/02-context-item-hook.spec.tsx | 16 ++--- .../react/02-context-task-hook.spec.tsx | 8 +-- specs/utils/wait.ts | 12 +++- 25 files changed, 312 insertions(+), 281 deletions(-) diff --git a/packages/react/core/src/logic/StreamContainer/StreamContainerComp.tsx b/packages/react/core/src/logic/StreamContainer/StreamContainerComp.tsx index 4300bb9b..204df318 100644 --- a/packages/react/core/src/logic/StreamContainer/StreamContainerComp.tsx +++ b/packages/react/core/src/logic/StreamContainer/StreamContainerComp.tsx @@ -1,4 +1,4 @@ -import {Ref, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react'; +import {ReactElement, Ref, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react'; import {createMarkdownStreamParser, MarkdownStreamParser} from '../../../../../extra/markdown/src'; import {className as compMessageClassName} from '../../../../../shared/src/ui/Message/create'; import { @@ -76,7 +76,7 @@ export const StreamContainerComp = function ( markdownOptions?.streamingAnimationSpeed, ]); - const rootElement = useMemo(() => { + const rootElement: ReactElement = useMemo(() => { if (responseRenderer) { const ResponseRendererComp = responseRenderer; return ( diff --git a/specs/specs/adapters/react/extras-conversationHistory.spec.tsx b/specs/specs/adapters/react/extras-conversationHistory.spec.tsx index 52afa464..b9127161 100644 --- a/specs/specs/adapters/react/extras-conversationHistory.spec.tsx +++ b/specs/specs/adapters/react/extras-conversationHistory.spec.tsx @@ -1,10 +1,11 @@ import {AiChat, ChatItem} from '@nlux-dev/react/src'; import {render} from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import {act} from 'react'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../utils/adapterBuilder'; import {AdapterController} from '../../../utils/adapters'; -import {waitForMdStreamToComplete, waitForRenderCycle} from '../../../utils/wait'; +import {waitForMdStreamToComplete, waitForReactRenderCycle} from '../../../utils/wait'; describe.each([ {dataTransferMode: 'fetch'}, @@ -34,12 +35,12 @@ describe.each([ , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(adapterController!.getLastExtras()?.conversationHistory).toEqual([...initialConversation]); @@ -58,12 +59,12 @@ describe.each([ , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'So what did you do?{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); if (dataTransferMode === 'fetch') { adapterController!.resolve('I helped you with your account.'); @@ -72,15 +73,16 @@ describe.each([ adapterController!.complete(); } + await act(() => waitForMdStreamToComplete(60)); + // Assert - await waitForMdStreamToComplete(60); expect(container.innerHTML).toEqual( expect.stringContaining('I helped you with your account.'), ); // Act await userEvent.type(textArea, 'Thank you!{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const newConversationHistory = adapterController!.getLastExtras()?.conversationHistory; @@ -112,12 +114,12 @@ describe.each([ />, ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(adapterController!.getLastExtras()?.conversationHistory).toBeUndefined(); @@ -144,12 +146,12 @@ describe.each([ />, ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(adapterController!.getLastExtras()?.conversationHistory).toEqual([ diff --git a/specs/specs/adapters/react/extras-personaOptions.spec.tsx b/specs/specs/adapters/react/extras-personaOptions.spec.tsx index 2c886dee..8fe34a32 100644 --- a/specs/specs/adapters/react/extras-personaOptions.spec.tsx +++ b/specs/specs/adapters/react/extras-personaOptions.spec.tsx @@ -1,10 +1,11 @@ import {AiChat} from '@nlux-dev/react/src'; import {render} from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import {act} from 'react'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../utils/adapterBuilder'; import {AdapterController} from '../../../utils/adapters'; -import {waitForMilliseconds, waitForRenderCycle} from '../../../utils/wait'; +import {waitForMdStreamToComplete, waitForMilliseconds, waitForReactRenderCycle} from '../../../utils/wait'; describe.each([ {dataTransferMode: 'fetch'}, @@ -39,15 +40,15 @@ describe.each([ , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert - expect(adapterController.getLastExtras()?.aiChatProps?.personaOptions) + expect(adapterController!.getLastExtras()?.aiChatProps?.personaOptions) .toEqual(testPersonaOptions); }); @@ -81,35 +82,37 @@ describe.each([ const {container, rerender} = render( , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); let textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); - adapterController.resolve('Cheers!'); - adapterController.complete(); - await waitForMilliseconds(100); + await act(async () => { + adapterController!.resolve('Cheers!'); + adapterController!.complete(); + await waitForMdStreamToComplete(20); + }); // Assert - expect(adapterController.getLastExtras()?.aiChatProps?.personaOptions) + expect(adapterController!.getLastExtras()?.aiChatProps?.personaOptions) .toEqual(testPersonaOptions); // Act rerender(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); textArea = container.querySelector('.nlux-comp-prmptBox > textarea')!; textArea.focus(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await userEvent.type(textArea, 'Bonjour{enter}'); await waitForMilliseconds(100); // Assert - expect(adapterController.getLastExtras()?.aiChatProps?.personaOptions) + expect(adapterController!.getLastExtras()?.aiChatProps?.personaOptions) .toEqual(newPersonaOptions); }); }); diff --git a/specs/specs/aiChat/behavior/react/exceptionsBox.spec.tsx b/specs/specs/aiChat/behavior/react/exceptionsBox.spec.tsx index adc55604..d59f6879 100644 --- a/specs/specs/aiChat/behavior/react/exceptionsBox.spec.tsx +++ b/specs/specs/aiChat/behavior/react/exceptionsBox.spec.tsx @@ -4,7 +4,7 @@ import userEvent from '@testing-library/user-event'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForRenderCycle} from '../../../../utils/wait'; +import {waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + theme', () => { let adapterController: AdapterController | undefined; @@ -22,14 +22,14 @@ describe(' + theme', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); // Act adapterController!.reject('Error message'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const exceptionBox = container.querySelector('.nlux-comp-exp_box')!; diff --git a/specs/specs/aiChat/behavior/react/markdown-fetch.spec.tsx b/specs/specs/aiChat/behavior/react/markdown-fetch.spec.tsx index 4f4473d1..a5ba227f 100644 --- a/specs/specs/aiChat/behavior/react/markdown-fetch.spec.tsx +++ b/specs/specs/aiChat/behavior/react/markdown-fetch.spec.tsx @@ -1,10 +1,11 @@ import {AiChat} from '@nlux-dev/react/src'; import {render} from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import {act} from 'react'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForMdStreamToComplete, waitForRenderCycle} from '../../../../utils/wait'; +import {waitForMdStreamToComplete, waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + fetch adapter + markdown', () => { let adapterController: AdapterController | undefined; @@ -25,14 +26,15 @@ describe(' + fetch adapter + markdown', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); + const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController!.resolve('**Hello Human!**'); - await waitForMdStreamToComplete(); + await act(() => waitForMdStreamToComplete()); // Assert const markdownContainer = container.querySelector('.nlux-md-cntr'); diff --git a/specs/specs/aiChat/behavior/react/markdown-stream.spec.tsx b/specs/specs/aiChat/behavior/react/markdown-stream.spec.tsx index 8fea97ac..09ba52d7 100644 --- a/specs/specs/aiChat/behavior/react/markdown-stream.spec.tsx +++ b/specs/specs/aiChat/behavior/react/markdown-stream.spec.tsx @@ -1,10 +1,11 @@ import {AiChat} from '@nlux-dev/react/src'; -import {render} from '@testing-library/react'; +import {render, waitFor} from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import {act} from 'react'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForMdStreamToComplete, waitForRenderCycle} from '../../../../utils/wait'; +import {waitForMdStreamToComplete, waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + stream adapter + markdown', () => { let adapterController: AdapterController | undefined; @@ -25,20 +26,26 @@ describe(' + stream adapter + markdown', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); + const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act - adapterController!.next('**Hello'); - adapterController!.next(' Human!**'); - await waitForMdStreamToComplete(); + await act(async () => { + adapterController!.next('**Hello'); + adapterController!.next(' Human!**'); + await waitForMdStreamToComplete(); + }); // Assert const markdownContainer = container.querySelector('.nlux-md-cntr'); expect(markdownContainer).toBeInTheDocument(); - expect(markdownContainer!.innerHTML).toBe('

Hello Human!

'); + + await waitFor(() => { + expect(markdownContainer!.innerHTML).toBe('

Hello Human!

'); + }); }); }); }); diff --git a/specs/specs/aiChat/behavior/react/submitPrompt-fetch.spec.tsx b/specs/specs/aiChat/behavior/react/submitPrompt-fetch.spec.tsx index fe4d5dda..727bacf8 100644 --- a/specs/specs/aiChat/behavior/react/submitPrompt-fetch.spec.tsx +++ b/specs/specs/aiChat/behavior/react/submitPrompt-fetch.spec.tsx @@ -1,10 +1,10 @@ import {AiChat} from '@nlux-dev/react/src'; -import {render} from '@testing-library/react'; +import {render, waitFor} from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForRenderCycle} from '../../../../utils/wait'; +import {waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + submit prompt + fetch adapter', () => { let adapterController: AdapterController | undefined; @@ -25,12 +25,12 @@ describe(' + submit prompt + fetch adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const activeSegmentSelector = '.nlux-chtRm-cntr > .nlux-chtRm-cnv-cntr > .nlux-chtRm-cnv-sgmts-cntr > .nlux-chtSgm-actv'; @@ -42,12 +42,12 @@ describe(' + submit prompt + fetch adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const loaderContainer = container.querySelector('.nlux-chtSgm-ldr-cntr'); @@ -58,12 +58,12 @@ describe(' + submit prompt + fetch adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(textArea.value).toBe('Hello'); @@ -75,17 +75,17 @@ describe(' + submit prompt + fetch adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; const activeSegmentSelector = '.nlux-chtRm-cntr > .nlux-chtRm-cnv-cntr > .nlux-chtRm-cnv-sgmts-cntr > .nlux-chtSgm'; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController!.resolve('Yo!'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const activeSegment = container.querySelector(activeSegmentSelector); @@ -112,15 +112,15 @@ describe(' + submit prompt + fetch adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController!.resolve('Yo!'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(textArea.value).toBe(''); @@ -132,14 +132,15 @@ describe(' + submit prompt + fetch adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); + const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController?.reject('Sorry user!'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const activeSegmentSelector = '.nlux-chtRm-cntr > .nlux-chtRm-cnv-cntr > .nlux-chtRm-cnv-sgmts-cntr > .nlux-chtSgm-actv'; @@ -151,7 +152,7 @@ describe(' + submit prompt + fetch adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; const activeSegmentSelector = '.nlux-chtRm-cntr > .nlux-chtRm-cnv-cntr > .nlux-chtRm-cnv-sgmts-cntr > .nlux-chtSgm-actv'; @@ -159,10 +160,10 @@ describe(' + submit prompt + fetch adapter', () => { // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController?.resolve('Hi! How can I help you?'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const completeSegment = container.querySelector(completeSegmentSelector); @@ -170,10 +171,10 @@ describe(' + submit prompt + fetch adapter', () => { // Act again await userEvent.type(textArea, 'How are you?{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController?.reject('Sorry user!'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const completeSegmentAgain = container.querySelector(completeSegmentSelector); @@ -187,17 +188,16 @@ describe(' + submit prompt + fetch adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController?.reject('Sorry user!'); - await waitForRenderCycle(); // Assert - expect(textArea.value).toBe('Hello'); + await waitFor(() => expect(textArea.value).toBe('Hello')); }); }); }); diff --git a/specs/specs/aiChat/behavior/react/submitPrompt-stream.spec.tsx b/specs/specs/aiChat/behavior/react/submitPrompt-stream.spec.tsx index 88a8c119..78b9db4f 100644 --- a/specs/specs/aiChat/behavior/react/submitPrompt-stream.spec.tsx +++ b/specs/specs/aiChat/behavior/react/submitPrompt-stream.spec.tsx @@ -1,10 +1,11 @@ import {AiChat} from '@nlux-dev/react/src'; -import {render} from '@testing-library/react'; +import {render, waitFor} from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import {act} from 'react'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForMilliseconds, waitForRenderCycle} from '../../../../utils/wait'; +import {waitForMilliseconds, waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + submit prompt + stream adapter', () => { let adapterController: AdapterController | undefined; @@ -25,12 +26,12 @@ describe(' + submit prompt + stream adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const activeSegmentSelector = '.nlux-chtRm-cntr > .nlux-chtRm-cnv-cntr > .nlux-chtRm-cnv-sgmts-cntr > .nlux-chtSgm-actv'; @@ -42,12 +43,12 @@ describe(' + submit prompt + stream adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const loaderContainer = container.querySelector('.nlux-chtSgm-ldr-cntr'); @@ -60,35 +61,33 @@ describe(' + submit prompt + stream adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); - + await waitForReactRenderCycle(); adapterController?.next('Hi!'); - await waitForMilliseconds(100); // Assert const activeSegmentSelector = '.nlux-chtSgm-actv'; const activeSegment = container.querySelector(activeSegmentSelector); - expect(activeSegment!.textContent).toContain('Hi!'); + await waitFor(() => expect(activeSegment!.textContent).toContain('Hi!')); }); it('Should display loader while streaming', async () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController?.next('Hi!'); - await waitForMilliseconds(100); + await act(() => waitForMilliseconds(100)); // Assert const loaderSelector = '.nlux-chtSgm-actv > .nlux-chtSgm-ldr-cntr'; @@ -100,15 +99,15 @@ describe(' + submit prompt + stream adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController?.next('Hi!'); - await waitForMilliseconds(100); + await act(() => waitForMilliseconds(100)); // Assert expect(textArea.value).toBe(''); @@ -118,18 +117,18 @@ describe(' + submit prompt + stream adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController?.next('Hi!'); - await waitForMilliseconds(100); + await act(() => waitForMilliseconds(100)); await userEvent.type(textArea, 'So?'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const promptBox = container.querySelector('.nlux-comp-prmptBox')!; @@ -144,20 +143,20 @@ describe(' + submit prompt + stream adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; const activeSegmentSelector = '.nlux-chtRm-cntr > .nlux-chtRm-cnv-cntr > .nlux-chtRm-cnv-sgmts-cntr > .nlux-chtSgm'; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController?.next('Hi!'); - await waitForRenderCycle(); + await act(() => waitForReactRenderCycle()); // Act adapterController!.complete(); - await waitForRenderCycle(); + await act(() => waitForReactRenderCycle()); // Assert const activeSegment = container.querySelector(activeSegmentSelector); @@ -169,20 +168,20 @@ describe(' + submit prompt + stream adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; const loaderSelector = '.nlux-chtSgm-actv > .nlux-chtSgm-ldr-cntr'; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController?.next('Hi!'); - await waitForRenderCycle(); + await act(() => waitForReactRenderCycle()); // Act adapterController!.complete(); - await waitForRenderCycle(); + await act(() => waitForReactRenderCycle()); // Assert const loader = container.querySelector(loaderSelector); @@ -195,15 +194,15 @@ describe(' + submit prompt + stream adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController?.error(new Error('An error occurred')); - await waitForRenderCycle(); + await act(() => waitForReactRenderCycle()); // Assert const activeSegmentSelector = '.nlux-chtRm-cntr > .nlux-chtRm-cnv-cntr > .nlux-chtRm-cnv-sgmts-cntr > .nlux-chtSgm-actv'; @@ -215,15 +214,15 @@ describe(' + submit prompt + stream adapter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController?.error(new Error('An error occurred')); - await waitForRenderCycle(); + await act(() => waitForReactRenderCycle()); // Assert expect(textArea.value).toBe('Hello'); diff --git a/specs/specs/aiChat/behavior/react/welcomeMessage.spec.tsx b/specs/specs/aiChat/behavior/react/welcomeMessage.spec.tsx index 6162eb32..7a9cd50a 100644 --- a/specs/specs/aiChat/behavior/react/welcomeMessage.spec.tsx +++ b/specs/specs/aiChat/behavior/react/welcomeMessage.spec.tsx @@ -3,7 +3,7 @@ import {render} from '@testing-library/react'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForRenderCycle} from '../../../../utils/wait'; +import {waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + bot persona + welcome message', () => { let adapterController: AdapterController | undefined; @@ -33,7 +33,7 @@ describe(' + bot persona + welcome message', () => { /> ); const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act const welcomeMessage = container.querySelector('.nlux-comp-wlc_msg')!; diff --git a/specs/specs/aiChat/options/react/className.spec.tsx b/specs/specs/aiChat/options/react/className.spec.tsx index 1c0248ab..d692cd4a 100644 --- a/specs/specs/aiChat/options/react/className.spec.tsx +++ b/specs/specs/aiChat/options/react/className.spec.tsx @@ -3,7 +3,7 @@ import {render} from '@testing-library/react'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForRenderCycle} from '../../../../utils/wait'; +import {waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + prop className', () => { let adapterController: AdapterController | undefined; @@ -21,7 +21,7 @@ describe(' + prop className', () => { // Arrange const aiChat = ; render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act const aiChatDom = document.querySelector('.nlux-AiChat-root')!; @@ -41,7 +41,7 @@ describe(' + prop className', () => { // Act rerender(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(aiChatDom.classList.length).toBe(3); @@ -77,7 +77,7 @@ describe(' + prop className', () => { // Act rerender(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(aiChatDom.classList.length).toBe(3); @@ -96,7 +96,7 @@ describe(' + prop className', () => { // Act rerender(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(aiChatDom.classList.length).toBe(2); diff --git a/specs/specs/aiChat/options/react/conversationOptions-autoScroll.spec.tsx b/specs/specs/aiChat/options/react/conversationOptions-autoScroll.spec.tsx index b6fc500e..c03f00bd 100644 --- a/specs/specs/aiChat/options/react/conversationOptions-autoScroll.spec.tsx +++ b/specs/specs/aiChat/options/react/conversationOptions-autoScroll.spec.tsx @@ -4,7 +4,7 @@ import userEvent from '@testing-library/user-event'; import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForMdStreamToComplete, waitForRenderCycle} from '../../../../utils/wait'; +import {waitForMdStreamToComplete, waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + conversationOptions + autoScroll', () => { let adapterController: AdapterController | undefined; @@ -25,14 +25,14 @@ describe(' + conversationOptions + autoScroll', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; const conversationContainer: any = container.querySelector('.nlux-chtRm-cnv-cntr')!; conversationContainer.scrollTo = vi.fn(); // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await waitForMdStreamToComplete(); // Assert @@ -44,14 +44,14 @@ describe(' + conversationOptions + autoScroll', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; const conversationContainer: any = container.querySelector('.nlux-chtRm-cnv-cntr')!; conversationContainer.scrollTo = vi.fn(); // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await waitForMdStreamToComplete(); // Assert @@ -68,14 +68,14 @@ describe(' + conversationOptions + autoScroll', () => { conversationOptions={{autoScroll: false}} />; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; const conversationContainer: any = container.querySelector('.nlux-chtRm-cnv-cntr')!; conversationContainer.scrollTo = vi.fn(); // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await waitForMdStreamToComplete(); // Assert @@ -90,14 +90,14 @@ describe(' + conversationOptions + autoScroll', () => { conversationOptions={{autoScroll: false}} />; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; const conversationContainer: any = container.querySelector('.nlux-chtRm-cnv-cntr')!; conversationContainer.scrollTo = vi.fn(); // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await waitForMdStreamToComplete(); // Assert diff --git a/specs/specs/aiChat/options/react/initialConversation.spec.tsx b/specs/specs/aiChat/options/react/initialConversation.spec.tsx index d7d909c3..e0111284 100644 --- a/specs/specs/aiChat/options/react/initialConversation.spec.tsx +++ b/specs/specs/aiChat/options/react/initialConversation.spec.tsx @@ -3,7 +3,7 @@ import {render} from '@testing-library/react'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForMilliseconds, waitForRenderCycle} from '../../../../utils/wait'; +import {waitForMilliseconds, waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + initialConversation prop', () => { let adapterController: AdapterController | undefined; @@ -27,7 +27,7 @@ describe(' + initialConversation prop', () => { const aiChat = ; render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act const aiChatDom = document.querySelector('.nlux-AiChat-root')!; @@ -70,7 +70,7 @@ describe(' + initialConversation prop', () => { const aiChat = ; render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act const aiChatDom = document.querySelector('.nlux-AiChat-root')!; @@ -140,7 +140,7 @@ describe(' + initialConversation prop', () => { // Act const aiChat = ; render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const aiChatDom = document.querySelector('.nlux-AiChat-root')!; @@ -172,7 +172,7 @@ describe(' + initialConversation prop', () => { messageOptions={{showCodeBlockCopyButton: false}} />; render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const aiChatDom = document.querySelector('.nlux-AiChat-root')!; @@ -213,7 +213,7 @@ describe(' + initialConversation prop', () => { messageOptions={{markdownLinkTarget: 'self'}} />; render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const aiChatDom = document.querySelector('.nlux-AiChat-root')!; @@ -241,7 +241,7 @@ describe(' + initialConversation prop', () => { messageOptions={{markdownLinkTarget: 'blank'}} />; render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const aiChatDom = document.querySelector('.nlux-AiChat-root')!; diff --git a/specs/specs/aiChat/options/react/layoutOptions-width.spec.tsx b/specs/specs/aiChat/options/react/layoutOptions-width.spec.tsx index 8da08993..ebf5a927 100644 --- a/specs/specs/aiChat/options/react/layoutOptions-width.spec.tsx +++ b/specs/specs/aiChat/options/react/layoutOptions-width.spec.tsx @@ -3,7 +3,7 @@ import {render} from '@testing-library/react'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForRenderCycle} from '../../../../utils/wait'; +import {waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + layoutOptions + width', () => { let adapterController: AdapterController | undefined; @@ -21,7 +21,7 @@ describe(' + layoutOptions + width', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act const aiChatDom: HTMLElement = container.querySelector('.nlux-AiChat-root')!; @@ -36,11 +36,11 @@ describe(' + layoutOptions + width', () => { // Arrange const aiChat = ; const {rerender, container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act rerender(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const aiChatDom: HTMLElement = container.querySelector('.nlux-AiChat-root')!; // Assert @@ -51,11 +51,11 @@ describe(' + layoutOptions + width', () => { // Arrange const aiChat = ; const {rerender, container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act rerender(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const aiChatDom: HTMLElement = container.querySelector('.nlux-AiChat-root')!; // Assert @@ -68,7 +68,7 @@ describe(' + layoutOptions + width', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act const aiChatDom: HTMLElement = container.querySelector('.nlux-AiChat-root')!; @@ -81,7 +81,7 @@ describe(' + layoutOptions + width', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act const aiChatDom: HTMLElement = container.querySelector('.nlux-AiChat-root')!; @@ -96,11 +96,11 @@ describe(' + layoutOptions + width', () => { // Arrange const aiChat = ; const {rerender, container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act rerender(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const aiChatDom: HTMLElement = container.querySelector('.nlux-AiChat-root')!; // Assert @@ -111,11 +111,11 @@ describe(' + layoutOptions + width', () => { // Arrange const aiChat = ; const {rerender, container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act rerender(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const aiChatDom: HTMLElement = container.querySelector('.nlux-AiChat-root')!; // Assert @@ -128,11 +128,11 @@ describe(' + layoutOptions + width', () => { // Arrange const aiChat = ; const {rerender, container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act rerender(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const aiChatDom: HTMLElement = container.querySelector('.nlux-AiChat-root')!; // Assert diff --git a/specs/specs/aiChat/options/react/messageOptions-markdownLinkTarget.spec.tsx b/specs/specs/aiChat/options/react/messageOptions-markdownLinkTarget.spec.tsx index ec43e0d7..e797ae3e 100644 --- a/specs/specs/aiChat/options/react/messageOptions-markdownLinkTarget.spec.tsx +++ b/specs/specs/aiChat/options/react/messageOptions-markdownLinkTarget.spec.tsx @@ -4,7 +4,7 @@ import userEvent from '@testing-library/user-event'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForRenderCycle} from '../../../../utils/wait'; +import {waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + messageOptions + markdownLinkTarget', () => { let adapterController: AdapterController | undefined = undefined; @@ -29,15 +29,15 @@ describe(' + messageOptions + markdownLinkTarget', () => { /> ); const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Give me a link please{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController!.resolve('Click [here](https://example.com)'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const markdownContainer = container.querySelector('.nlux_cht_itm_in .nlux-md-cntr'); @@ -57,11 +57,11 @@ describe(' + messageOptions + markdownLinkTarget', () => { /> ); const {container, rerender} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Give me a link please{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act rerender( @@ -70,10 +70,10 @@ describe(' + messageOptions + markdownLinkTarget', () => { messageOptions={{markdownLinkTarget: 'blank'}} />, ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController!.resolve('Click [here](https://example.com)'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const markdownContainer = container.querySelector('.nlux_cht_itm_in .nlux-md-cntr'); @@ -96,15 +96,15 @@ describe(' + messageOptions + markdownLinkTarget', () => { /> ); const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Give me a link please{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController!.resolve('Click [here](https://example.com)'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const markdownContainer = container.querySelector('.nlux_cht_itm_in .nlux-md-cntr'); @@ -125,11 +125,11 @@ describe(' + messageOptions + markdownLinkTarget', () => { /> ); const {container, rerender} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Give me a link please{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act rerender( @@ -138,10 +138,10 @@ describe(' + messageOptions + markdownLinkTarget', () => { messageOptions={{markdownLinkTarget: 'self'}} />, ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController!.resolve('Click [here](https://example.com)'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const markdownContainer = container.querySelector('.nlux_cht_itm_in .nlux-md-cntr'); @@ -163,15 +163,15 @@ describe(' + messageOptions + markdownLinkTarget', () => { /> ); const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Give me a link please{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController!.resolve('Click [here](https://example.com)'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const markdownContainer = container.querySelector('.nlux_cht_itm_in .nlux-md-cntr'); diff --git a/specs/specs/aiChat/options/react/messageOptions-responseComponent.spec.tsx b/specs/specs/aiChat/options/react/messageOptions-responseComponent.spec.tsx index af84950d..55438dda 100644 --- a/specs/specs/aiChat/options/react/messageOptions-responseComponent.spec.tsx +++ b/specs/specs/aiChat/options/react/messageOptions-responseComponent.spec.tsx @@ -1,10 +1,11 @@ import {AiChat, ResponseComponent} from '@nlux-dev/react/src'; -import {render} from '@testing-library/react'; +import {render, waitFor} from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import {act} from 'react'; import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForMdStreamToComplete, waitForRenderCycle} from '../../../../utils/wait'; +import {waitForMdStreamToComplete, waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + messageOptions + responseComponent', () => { let adapterController: AdapterController | undefined = undefined; @@ -34,14 +35,14 @@ describe(' + messageOptions + responseComponent', () => { />, ); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController!.resolve('Yo!'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const responseElement = container.querySelector('.nlux_cht_itm_in'); @@ -67,14 +68,14 @@ describe(' + messageOptions + responseComponent', () => { />, ); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController!.resolve('Yo!'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(customResponseComponentSpy).toHaveBeenCalledWith( @@ -97,24 +98,24 @@ describe(' + messageOptions + responseComponent', () => { adapter={adapterController!.adapter} messageOptions={{responseComponent: customResponseComponentSpy}} />); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act rerender(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController!.resolve('Yo!'); - await waitForMdStreamToComplete(); + await act(() => waitForMdStreamToComplete()); // Assert const responseElement = container.querySelector('.nlux_cht_itm_in'); @@ -155,26 +156,30 @@ describe(' + messageOptions + responseComponent', () => { />, ); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController!.next('Yo!'); - await waitForMdStreamToComplete(); + await act(() => waitForMdStreamToComplete()); // Assert const chatItemReceived = container.querySelector('.nlux-chtRm-cnv-sgmts-cntr .nlux_cht_itm_in'); const mdContainer = chatItemReceived!.querySelector('.nlux-md-cntr'); - expect(mdContainer!.innerHTML).toEqual('

Yo!

'); + await waitFor(() => { + expect(mdContainer!.innerHTML).toEqual('

Yo!

'); + }); // Act adapterController!.next(' What\'s up?'); - await waitForMdStreamToComplete(); + await act(() => waitForMdStreamToComplete()); // Assert - Streamed content should have been appended to the existing content - expect(mdContainer!.innerHTML).toEqual('

Yo! What\'s up?

'); + await waitFor(() => { + expect(mdContainer!.innerHTML).toEqual('

Yo! What\'s up?

'); + }); // Asset - Custom component should have been called with the correct props expect(customResponseComponentSpy).toHaveBeenCalledWith( diff --git a/specs/specs/aiChat/options/react/messageOptions-showCodeBlockCopyButton.spec.tsx b/specs/specs/aiChat/options/react/messageOptions-showCodeBlockCopyButton.spec.tsx index e1bb7f8e..ced15be8 100644 --- a/specs/specs/aiChat/options/react/messageOptions-showCodeBlockCopyButton.spec.tsx +++ b/specs/specs/aiChat/options/react/messageOptions-showCodeBlockCopyButton.spec.tsx @@ -1,10 +1,11 @@ import {AiChat} from '@nlux-dev/react/src'; import {render} from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import {act} from 'react'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForMdStreamToComplete, waitForRenderCycle} from '../../../../utils/wait'; +import {waitForMdStreamToComplete, waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + messageOptions + showCodeBlockCopyButton', () => { let adapterController: AdapterController | undefined = undefined; @@ -29,15 +30,15 @@ describe(' + messageOptions + showCodeBlockCopyButton', () => { /> ); const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Give me some code block please{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController!.resolve('This is code block\n```js\nconsole.log("Hello, World!");\n```\n'); - await waitForMdStreamToComplete(100); + await act(() => waitForMdStreamToComplete(100)); // Assert const markdownContainer = container.querySelector('.nlux_cht_itm_in .nlux-md-cntr'); @@ -58,15 +59,15 @@ describe(' + messageOptions + showCodeBlockCopyButton', () => { /> ); const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Give me some code block please{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController!.resolve('This is code block\n```js\nconsole.log("Hello, World!");\n```\n'); - await waitForMdStreamToComplete(100); + await act(() => waitForMdStreamToComplete(100)); // Assert const markdownContainer = container.querySelector('.nlux_cht_itm_in .nlux-md-cntr'); @@ -87,15 +88,15 @@ describe(' + messageOptions + showCodeBlockCopyButton', () => { /> ); const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Give me some code block please{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController!.resolve('This is code block\n```js\nconsole.log("Hello, World!");\n```\n'); - await waitForMdStreamToComplete(100); + await act(() => waitForMdStreamToComplete(100)); // Assert const markdownContainer = container.querySelector('.nlux_cht_itm_in .nlux-md-cntr'); diff --git a/specs/specs/aiChat/options/react/messageOptions-syntaxHighlighter.spec.tsx b/specs/specs/aiChat/options/react/messageOptions-syntaxHighlighter.spec.tsx index b75855ea..71c274ad 100644 --- a/specs/specs/aiChat/options/react/messageOptions-syntaxHighlighter.spec.tsx +++ b/specs/specs/aiChat/options/react/messageOptions-syntaxHighlighter.spec.tsx @@ -5,7 +5,7 @@ import userEvent from '@testing-library/user-event'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForRenderCycle} from '../../../../utils/wait'; +import {waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + messageOptions + syntaxHighlighter', () => { let adapterController: AdapterController | undefined = undefined; @@ -34,15 +34,15 @@ describe(' + messageOptions + syntaxHighlighter', () => { /> ); const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Write some JS code{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController!.resolve('```js\nvar someJsCode = true;\n\n```'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const responseElement = container.querySelector('.nlux_cht_itm_in .nlux-md-cntr'); @@ -57,15 +57,15 @@ describe(' + messageOptions + syntaxHighlighter', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Write some JS code{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act adapterController!.resolve('```\nvar someJsCode = true;\n```'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const responseElement = container.querySelector('.nlux_cht_itm_in .nlux-md-cntr'); @@ -85,7 +85,7 @@ describe(' + messageOptions + syntaxHighlighter', () => { /> ); const {container, rerender} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act rerender( @@ -94,14 +94,14 @@ describe(' + messageOptions + syntaxHighlighter', () => { messageOptions={{syntaxHighlighter: undefined}} />, ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Write some JS code{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController!.resolve('```js\nvar someJsCode = true;\n```'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const responseElement = container.querySelector('.nlux_cht_itm_in .nlux-md-cntr'); diff --git a/specs/specs/aiChat/options/react/personaOptions-bot.spec.tsx b/specs/specs/aiChat/options/react/personaOptions-bot.spec.tsx index 59564e63..748e8ed5 100644 --- a/specs/specs/aiChat/options/react/personaOptions-bot.spec.tsx +++ b/specs/specs/aiChat/options/react/personaOptions-bot.spec.tsx @@ -4,7 +4,7 @@ import userEvent from '@testing-library/user-event'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForRenderCycle} from '../../../../utils/wait'; +import {waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + personaOptions + bot', () => { let adapterController: AdapterController | undefined; @@ -36,14 +36,14 @@ describe(' + personaOptions + bot', () => { // Act const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController?.resolve('Hi there!'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const selector = '.nlux_cht_itm_in > .nlux-comp-avtr > .avtr_ctn'; @@ -65,18 +65,18 @@ describe(' + personaOptions + bot', () => { // Act const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController?.resolve('Hi there!'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const selector = '.nlux_cht_itm_in > .nlux-comp-avtr > .avtr_ctn > .avtr_img'; - const avatarImage = container.querySelector(selector); + const avatarImage = container.querySelector(selector) as HTMLElement | null; expect(avatarImage).toBeInTheDocument(); expect(avatarImage!.style.backgroundImage).toBe('url(https://bot-image-url)'); }); @@ -95,14 +95,14 @@ describe(' + personaOptions + bot', () => { // Act const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController?.resolve('Hi there!'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const selector = '.nlux_cht_itm_in > .nlux-comp-avtr > .avtr_ctn > .avtr_ltr'; @@ -126,20 +126,20 @@ describe(' + personaOptions + bot', () => { />; const {container, rerender} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController!.resolve('Hi, how can I help you?'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await userEvent.type(textArea, 'Tell me a funny joke!{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController!.resolve('Why did the chicken cross the road? To get to the other side!'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act rerender( + personaOptions + bot', () => { }} />); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const selector = '.nlux_cht_itm_in > .nlux-comp-avtr > .avtr_ctn > .avtr_img'; @@ -186,14 +186,14 @@ describe(' + personaOptions + bot', () => { // Act const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController?.resolve('Hi there!'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const selector = '.nlux_cht_itm_in > .nlux-comp-avtr > #jsx-avatar'; @@ -215,14 +215,14 @@ describe(' + personaOptions + bot', () => { // Act const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController?.resolve('Hi there!'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const selector = '.nlux_cht_itm_in > .nlux-comp-avtr > #jsx-avatar'; diff --git a/specs/specs/aiChat/options/react/personaOptions-user.spec.tsx b/specs/specs/aiChat/options/react/personaOptions-user.spec.tsx index 8724173e..53fca38b 100644 --- a/specs/specs/aiChat/options/react/personaOptions-user.spec.tsx +++ b/specs/specs/aiChat/options/react/personaOptions-user.spec.tsx @@ -4,7 +4,7 @@ import userEvent from '@testing-library/user-event'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForRenderCycle} from '../../../../utils/wait'; +import {waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + personaOptions + user', () => { let adapterController: AdapterController | undefined; @@ -36,11 +36,11 @@ describe(' + personaOptions + user', () => { // Act const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const selector = '.nlux_cht_itm_out > .nlux-comp-avtr > .avtr_ctn'; @@ -62,15 +62,15 @@ describe(' + personaOptions + user', () => { // Act const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const selector = '.nlux_cht_itm_out > .nlux-comp-avtr > .avtr_ctn > .avtr_img'; - const avatarImageContainer = container.querySelector(selector); + const avatarImageContainer = container.querySelector(selector) as HTMLDivElement | null; expect(avatarImageContainer).toBeInTheDocument(); expect(avatarImageContainer!.style.backgroundImage).toBe('url(https://user-image-url)'); }); @@ -89,11 +89,11 @@ describe(' + personaOptions + user', () => { // Act const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const selector = '.nlux_cht_itm_out > .nlux-comp-avtr > .avtr_ctn > .avtr_ltr'; @@ -117,17 +117,17 @@ describe(' + personaOptions + user', () => { />; const {container, rerender} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); adapterController!.resolve('Hi, how can I help you?'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await userEvent.type(textArea, 'Tell me a funny joke!{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act rerender( + personaOptions + user', () => { }} />); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const selector = '.nlux_cht_itm_out > .nlux-comp-avtr > .avtr_ctn > .avtr_img'; @@ -174,11 +174,11 @@ describe(' + personaOptions + user', () => { // Act const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const selector = '.nlux_cht_itm_out > .nlux-comp-avtr > #jsx-avatar'; @@ -200,11 +200,11 @@ describe(' + personaOptions + user', () => { // Act const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; await userEvent.type(textArea, 'Hello{enter}'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert const selector = '.nlux_cht_itm_out > .nlux-comp-avtr > #jsx-avatar'; diff --git a/specs/specs/aiChat/options/react/promptBoxOptions-autoFocus.spec.tsx b/specs/specs/aiChat/options/react/promptBoxOptions-autoFocus.spec.tsx index add76564..ecd1e7cb 100644 --- a/specs/specs/aiChat/options/react/promptBoxOptions-autoFocus.spec.tsx +++ b/specs/specs/aiChat/options/react/promptBoxOptions-autoFocus.spec.tsx @@ -4,7 +4,7 @@ import userEvent from '@testing-library/user-event'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForRenderCycle} from '../../../../utils/wait'; +import {waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + promptBoxOptions + autoFocus', () => { let adapterController: AdapterController | undefined; @@ -22,7 +22,7 @@ describe(' + promptBoxOptions + autoFocus', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; @@ -37,14 +37,14 @@ describe(' + promptBoxOptions + autoFocus', () => { // Arrange const aiChat = ; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act await userEvent.type(textArea, 'Hello{enter}'); adapterController?.resolve('Response'); textArea.blur(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(document.activeElement).not.toBe(textArea); @@ -58,7 +58,7 @@ describe(' + promptBoxOptions + autoFocus', () => { autoFocus: true, }}/>; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; @@ -74,12 +74,12 @@ describe(' + promptBoxOptions + autoFocus', () => { autoFocus: true, }}/>; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; // Act textArea.focus(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(document.activeElement).toBe(textArea); @@ -91,14 +91,14 @@ describe(' + promptBoxOptions + autoFocus', () => { autoFocus: true, }}/>; const {container} = render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); const textArea: HTMLTextAreaElement = container.querySelector('.nlux-comp-prmptBox > textarea')!; textArea.blur(); // Act await userEvent.type(textArea, 'Hello{enter}'); adapterController?.reject('Error message'); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(document.activeElement).toBe(textArea); diff --git a/specs/specs/aiChat/options/react/themeId.spec.tsx b/specs/specs/aiChat/options/react/themeId.spec.tsx index 7f7cfc7b..b3234f7c 100644 --- a/specs/specs/aiChat/options/react/themeId.spec.tsx +++ b/specs/specs/aiChat/options/react/themeId.spec.tsx @@ -3,7 +3,7 @@ import {render} from '@testing-library/react'; import {afterEach, beforeEach, describe, expect, it} from 'vitest'; import {adapterBuilder} from '../../../../utils/adapterBuilder'; import {AdapterController} from '../../../../utils/adapters'; -import {waitForRenderCycle} from '../../../../utils/wait'; +import {waitForReactRenderCycle} from '../../../../utils/wait'; describe(' + prop themeId', () => { let adapterController: AdapterController | undefined; @@ -21,7 +21,7 @@ describe(' + prop themeId', () => { // Arrange const aiChat = ; render(aiChat); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Act const aiChatDom = document.querySelector('.nlux-AiChat-root')!; @@ -53,7 +53,7 @@ describe(' + prop themeId', () => { // Act rerender(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(aiChatDom.className).toContain('nlux-theme-vienna'); @@ -69,7 +69,7 @@ describe(' + prop themeId', () => { // Act rerender(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(aiChatDom.className).toContain('nlux-theme-luna'); diff --git a/specs/specs/aiContext/react/01-create-context.spec.tsx b/specs/specs/aiContext/react/01-create-context.spec.tsx index 83efbf8f..ff12b9e7 100644 --- a/specs/specs/aiContext/react/01-create-context.spec.tsx +++ b/specs/specs/aiContext/react/01-create-context.spec.tsx @@ -1,10 +1,10 @@ import {AiContext as CoreAiContext} from '@nlux-dev/core/src'; import {createAiContext} from '@nlux-dev/react/src'; -import {render} from '@testing-library/react'; -import {useContext} from 'react'; +import {render, waitFor} from '@testing-library/react'; +import {act, useContext} from 'react'; import {describe, expect, it, vi} from 'vitest'; import {createContextAdapterController} from '../../../utils/contextAdapterBuilder'; -import {waitForMilliseconds, waitForRenderCycle} from '../../../utils/wait'; +import {waitForMilliseconds, waitForReactRenderCycle} from '../../../utils/wait'; describe('React context provider', () => { it('should initialize the AI context and get the contextId', async () => { @@ -34,18 +34,20 @@ describe('React context provider', () => { // Act render(component); render(); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert - expect(adapter.create).toHaveBeenCalledWith({ - appName: { - value: 'My App', - description: 'The name of the application being used', - }, - appVersion: { - value: '0.1.0', - description: 'The version of the application', - }, + await waitFor(() => { + expect(adapter.create).toHaveBeenCalledWith({ + appName: { + value: 'My App', + description: 'The name of the application being used', + }, + appVersion: { + value: '0.1.0', + description: 'The version of the application', + }, + }); }); }); @@ -67,14 +69,14 @@ describe('React context provider', () => { // Act render(component); - await waitForRenderCycle(); + await waitForReactRenderCycle(); // Assert expect(document.body).toHaveTextContent('CTX LOADING'); // Act - await waitForMilliseconds(delayBeforeCreateContext + 1); - await waitForRenderCycle(); + await act(() => waitForMilliseconds(delayBeforeCreateContext + 1)); + await waitForReactRenderCycle(); expect(document.body).not.toHaveTextContent('CTX LOADING'); }); @@ -97,8 +99,8 @@ describe('React context provider', () => { // Act render(component); - await waitForRenderCycle(); - await waitForMilliseconds(delayBeforeCreateContext * 1.1); + await waitForReactRenderCycle(); + await act(() => waitForMilliseconds(delayBeforeCreateContext * 1.1)); // Assert expect(document.body).toHaveTextContent('CTX ERROR: Failed to initialize context'); diff --git a/specs/specs/aiContext/react/02-context-item-hook.spec.tsx b/specs/specs/aiContext/react/02-context-item-hook.spec.tsx index ba4c9480..ef2a3a9c 100644 --- a/specs/specs/aiContext/react/02-context-item-hook.spec.tsx +++ b/specs/specs/aiContext/react/02-context-item-hook.spec.tsx @@ -4,7 +4,7 @@ import {render} from '@testing-library/react'; import {useContext} from 'react'; import {describe, expect, it, vi} from 'vitest'; import {createContextAdapterController} from '../../../utils/contextAdapterBuilder'; -import {waitForRenderCycle} from '../../../utils/wait'; +import {waitForReactRenderCycle} from '../../../utils/wait'; describe('AI context item hook', () => { it('should send the item to AI context', async () => { @@ -30,7 +30,7 @@ describe('AI context item hook', () => { , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await coreContext!.flush(); // First assert + Get item ID @@ -71,7 +71,7 @@ describe('AI context item hook', () => { , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await coreContext!.flush(); // First assert + Get item ID @@ -86,7 +86,7 @@ describe('AI context item hook', () => { , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await coreContext!.flush(); // Second assert @@ -126,7 +126,7 @@ describe('AI context item hook', () => { /> , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await coreContext!.flush(); // First assert + Get item ID @@ -144,7 +144,7 @@ describe('AI context item hook', () => { /> , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await coreContext!.flush(); // Second assert @@ -182,7 +182,7 @@ describe('AI context item hook', () => { , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await coreContext!.flush(); // First assert + Get item ID @@ -197,7 +197,7 @@ describe('AI context item hook', () => { No more components with AI context! , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await coreContext!.flush(); // Second assert diff --git a/specs/specs/aiContext/react/02-context-task-hook.spec.tsx b/specs/specs/aiContext/react/02-context-task-hook.spec.tsx index 8ac7a14a..8ffa1eb8 100644 --- a/specs/specs/aiContext/react/02-context-task-hook.spec.tsx +++ b/specs/specs/aiContext/react/02-context-task-hook.spec.tsx @@ -5,7 +5,7 @@ import {render} from '@testing-library/react'; import {useContext} from 'react'; import {describe, expect, it, vi} from 'vitest'; import {createContextAdapterController} from '../../../utils/contextAdapterBuilder'; -import {waitForRenderCycle} from '../../../utils/wait'; +import {waitForReactRenderCycle} from '../../../utils/wait'; describe('AI context task hook', () => { it('should send the task information to AI context', async () => { @@ -41,7 +41,7 @@ describe('AI context task hook', () => { /> , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await coreContext!.flush(); // Assert @@ -92,7 +92,7 @@ describe('AI context task hook', () => { /> , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await coreContext!.flush(); // Get task ID @@ -107,7 +107,7 @@ describe('AI context task hook', () => { No more components with AI context! , ); - await waitForRenderCycle(); + await waitForReactRenderCycle(); await coreContext!.flush(); // Assert diff --git a/specs/utils/wait.ts b/specs/utils/wait.ts index 3467e957..48234f0d 100644 --- a/specs/utils/wait.ts +++ b/specs/utils/wait.ts @@ -1,7 +1,17 @@ -export const waitForRenderCycle = () => new Promise(resolve => { +import {act} from 'react'; + +export const waitForRenderCycle = async () => new Promise(resolve => { requestAnimationFrame(resolve); }); +export const waitForReactRenderCycle = async () => { + const animationFramePromise = new Promise(resolve => { + requestAnimationFrame(resolve); + }); + + await act(() => animationFramePromise); +}; + export const waitForMilliseconds = (milliseconds: number) => new Promise(resolve => { setTimeout(resolve, milliseconds); });