Skip to content

Commit c88fd75

Browse files
committed
Improves Instruqt lab context tests
Updates tests to use `waitFor` for asynchronous state updates, ensuring accurate state validation and preventing race conditions. Also, fixes a bug where the `active` state was not being set correctly when a new lab is opened.
1 parent 3465daa commit c88fd75

File tree

2 files changed

+73
-55
lines changed

2 files changed

+73
-55
lines changed

src/contexts/instruqt-lab/__tests__/instruqt-lab.test.tsx

Lines changed: 69 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
*/
55

66
import { describe, it, expect, vi, beforeEach } from 'vitest'
7-
import { render, screen, fireEvent, act } from '@testing-library/react'
7+
import { render, screen, fireEvent, act, waitFor } from '@testing-library/react'
88
import { trackSandboxEvent, SANDBOX_EVENT } from 'lib/posthog-events'
99
import React from 'react'
10-
import InstruqtProvider, { useInstruqtEmbed } from '../index'
10+
import { InstruqtProvider, useInstruqtEmbed } from '../index'
1111

1212
vi.mock('components/lab-embed/embed-element', () => ({
1313
default: () => null,
@@ -163,28 +163,40 @@ describe('InstruqtEmbed Context', () => {
163163

164164
it('persists state changes to localStorage', async () => {
165165
const TestComponent = () => {
166-
const { openLab } = useInstruqtEmbed()
167-
return <button onClick={() => openLab('test-lab-id')}>Open Lab</button>
166+
const { openLab, labId, active } = useInstruqtEmbed()
167+
return (
168+
<>
169+
<button onClick={() => openLab('test-lab-id')}>Open Lab</button>
170+
<div data-testid="lab-id">{labId || 'no-lab'}</div>
171+
<div data-testid="active">{active ? 'true' : 'false'}</div>
172+
</>
173+
)
168174
}
169175

170-
await act(async () => {
171-
render(
172-
<InstruqtProvider>
173-
<TestComponent />
174-
</InstruqtProvider>
175-
)
176-
})
176+
render(
177+
<InstruqtProvider>
178+
<TestComponent />
179+
</InstruqtProvider>
180+
)
177181

178-
await act(async () => {
179-
fireEvent.click(await screen.findByText('Open Lab'))
182+
fireEvent.click(screen.getByText('Open Lab'))
183+
184+
await waitFor(() => {
185+
expect(screen.getByTestId('lab-id')).toHaveTextContent('test-lab-id')
186+
expect(screen.getByTestId('active')).toHaveTextContent('true')
180187
})
181188

182-
expect(setItemSpy).toHaveBeenCalledWith(
183-
'instruqt-lab-state',
184-
JSON.stringify({
185-
active: true,
186-
storedLabId: 'test-lab-id',
187-
})
189+
await waitFor(
190+
() => {
191+
expect(setItemSpy).toHaveBeenCalledWith(
192+
'instruqt-lab-state',
193+
JSON.stringify({
194+
active: true,
195+
storedLabId: 'test-lab-id',
196+
})
197+
)
198+
},
199+
{ timeout: 3000 }
188200
)
189201
})
190202

@@ -194,24 +206,25 @@ describe('InstruqtEmbed Context', () => {
194206
return <button onClick={() => openLab('test-lab-id')}>Open Lab</button>
195207
}
196208

197-
await act(async () => {
198-
render(
199-
<InstruqtProvider>
200-
<TestComponent />
201-
</InstruqtProvider>
202-
)
203-
})
204-
205-
await act(async () => {
206-
fireEvent.click(await screen.findByText('Open Lab'))
207-
})
209+
render(
210+
<InstruqtProvider>
211+
<TestComponent />
212+
</InstruqtProvider>
213+
)
208214

209-
expect(mockTrackSandboxEvent).toHaveBeenCalledWith(
210-
SANDBOX_EVENT.SANDBOX_OPEN,
211-
{
212-
labId: 'test-lab-id',
213-
page: '/test-path',
214-
}
215+
fireEvent.click(screen.getByText('Open Lab'))
216+
217+
await waitFor(
218+
() => {
219+
expect(mockTrackSandboxEvent).toHaveBeenCalledWith(
220+
SANDBOX_EVENT.SANDBOX_OPEN,
221+
{
222+
labId: 'test-lab-id',
223+
page: '/test-path',
224+
}
225+
)
226+
},
227+
{ timeout: 3000 }
215228
)
216229
})
217230

@@ -233,28 +246,29 @@ describe('InstruqtEmbed Context', () => {
233246
)
234247
}
235248

236-
await act(async () => {
237-
render(
238-
<InstruqtProvider>
239-
<TestComponent />
240-
</InstruqtProvider>
241-
)
242-
})
249+
render(
250+
<InstruqtProvider>
251+
<TestComponent />
252+
</InstruqtProvider>
253+
)
243254

244-
await act(async () => {
245-
fireEvent.click(await screen.findByTestId('open'))
246-
})
255+
fireEvent.click(screen.getByTestId('open'))
247256

248-
await act(async () => {
249-
fireEvent.click(await screen.findByTestId('close'))
250-
})
257+
await new Promise((resolve) => setTimeout(resolve, 100))
251258

252-
expect(mockTrackSandboxEvent).toHaveBeenCalledWith(
253-
SANDBOX_EVENT.SANDBOX_CLOSED,
254-
{
255-
labId: 'close-test-lab-id',
256-
page: '/test-path',
257-
}
259+
fireEvent.click(screen.getByTestId('close'))
260+
261+
await waitFor(
262+
() => {
263+
expect(mockTrackSandboxEvent).toHaveBeenCalledWith(
264+
SANDBOX_EVENT.SANDBOX_CLOSED,
265+
{
266+
labId: 'close-test-lab-id',
267+
page: '/test-path',
268+
}
269+
)
270+
},
271+
{ timeout: 3000 }
258272
)
259273
})
260274
})

src/contexts/instruqt-lab/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ function InstruqtProvider({
257257

258258
const labExists = SANDBOX_CONFIG.labs?.some((lab) => {
259259
return (
260+
lab.labId === newLabId ||
260261
lab.instruqtTrack === newLabId ||
261262
lab.instruqtTrack?.split('?')[0] === newLabId.split('?')[0] ||
262263
(lab.scenario && newLabId.includes(lab.scenario))
@@ -275,6 +276,7 @@ function InstruqtProvider({
275276
}
276277
if (newLabId !== labId || !active) {
277278
setLabId(newLabId)
279+
setActive(true)
278280
}
279281
},
280282
[labId, active, hasConfigError, configErrors]
@@ -340,6 +342,8 @@ function InstruqtProvider({
340342
)
341343
}
342344

345+
export { InstruqtProvider }
346+
343347
export default dynamic(() => Promise.resolve(InstruqtProvider), {
344348
ssr: false,
345349
})

0 commit comments

Comments
 (0)