Skip to content

Commit ace3370

Browse files
committed
Use waitFor() instead of setTimeout
1 parent 0f18f50 commit ace3370

File tree

5 files changed

+55
-30
lines changed

5 files changed

+55
-30
lines changed

sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/src/__tests__/clusters/Clusters.test.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import { act } from 'react';
1818

1919
import { Clusters } from '../../clusters/Clusters';
2020

21+
import { waitFor } from '@testing-library/dom';
22+
2123
let container: null | Element = null;
2224
let root: Root | null = null;
2325
beforeEach(() => {
@@ -76,9 +78,12 @@ it('renders a data-table', async () => {
7678

7779
await act(async () => {
7880
clustersRef.current?.setState({ clusters: testData });
79-
await new Promise(resolve => setTimeout(resolve, 100));
8081
});
8182

83+
await waitFor(() =>
84+
expect(container.querySelector('.mdc-data-table__table')).toBeTruthy()
85+
);
86+
8287
const topAppBarHeader: Element = container.firstElementChild;
8388
expect(topAppBarHeader.tagName).toBe('HEADER');
8489
expect(topAppBarHeader.getAttribute('class')).toContain('mdc-top-app-bar');

sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/src/__tests__/common/HtmlView.test.tsx

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { createRoot, Root } from 'react-dom/client';
2121
import { act } from 'react';
2222

2323
import { HtmlView, IHtmlProvider, importHtml } from '../../common/HtmlView';
24+
import { waitFor } from '@testing-library/dom';
2425

2526
let container: null | Element = null;
2627
let root: Root | null = null;
@@ -65,19 +66,22 @@ describe('HtmlView', () => {
6566
});
6667
await act(async () => {
6768
htmlViewRef.current?.updateRender();
68-
await new Promise(resolve => setTimeout(resolve, 100));
6969
});
70-
const htmlViewElement: Element = container.firstElementChild;
71-
expect(htmlViewElement.tagName).toBe('DIV');
72-
expect(htmlViewElement.innerHTML).toBe('<div>Test</div>');
70+
71+
await waitFor(() => {
72+
const htmlViewElement: Element = container.firstElementChild;
73+
expect(htmlViewElement.tagName).toBe('DIV');
74+
expect(htmlViewElement.innerHTML).toBe('<div>Test</div>');
75+
});
76+
7377
expect(spiedConsole).toHaveBeenCalledWith(1);
7478
expect(spiedConsole).toHaveBeenCalledWith(2);
7579
expect(spiedConsole).toHaveBeenCalledTimes(2);
7680
});
7781

7882
it(
7983
'only executes incrementally updated Javascript ' +
80-
'as html provider updated',
84+
'as html provider updated',
8185
async () => {
8286
const htmlViewRef: React.RefObject<HtmlView> =
8387
React.createRef<HtmlView>();
@@ -93,11 +97,15 @@ describe('HtmlView', () => {
9397
});
9498
await act(async () => {
9599
htmlViewRef.current?.updateRender();
96-
await new Promise(resolve => setTimeout(resolve, 100));
97100
});
98-
expect(spiedConsole).toHaveBeenCalledWith(1);
99-
expect(spiedConsole).toHaveBeenCalledTimes(1);
101+
102+
await waitFor(() => {
103+
expect(spiedConsole).toHaveBeenCalledWith(1);
104+
expect(spiedConsole).toHaveBeenCalledTimes(1);
105+
});
106+
100107
fakeHtmlProvider.script.push('console.log(2);');
108+
101109
await act(async () => {
102110
const htmlView = htmlViewRef.current;
103111
if (htmlView) {

sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/src/__tests__/inspector/Inspectables.test.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { createRoot, Root } from 'react-dom/client';
1717
import { act } from 'react';
1818

1919
import { Inspectables } from '../../inspector/Inspectables';
20+
import { waitFor } from '@testing-library/dom';
2021

2122
jest.mock('../../inspector/InspectableList', () => {
2223
const FakeInspectableList = function (): React.ReactNode {
@@ -115,13 +116,14 @@ it('renders inspectables as a list of collapsible lists', async () => {
115116

116117
await act(async () => {
117118
inspectablesRef.current?.setState({ inspectables: testData });
118-
await new Promise(resolve => setTimeout(resolve, 100));
119119
});
120120

121-
const listElement: Element = container.firstElementChild;
122-
expect(listElement.tagName).toBe('UL');
123-
expect(listElement.getAttribute('class')).toContain('mdc-list');
124-
// Only checks the length of dummy InspectableList items. Each InspectableList
125-
// has its own unit tests.
126-
expect(listElement.children).toHaveLength(2);
121+
await waitFor(() => {
122+
const listElement: Element = container.firstElementChild;
123+
expect(listElement.tagName).toBe('UL');
124+
expect(listElement.getAttribute('class')).toContain('mdc-list');
125+
// Only checks the length of dummy InspectableList items. Each InspectableList
126+
// has its own unit tests.
127+
expect(listElement.children).toHaveLength(2);
128+
})
127129
});

sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/src/__tests__/inspector/InteractiveInspector.test.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { act } from 'react';
1919
import { InteractiveInspector } from '../../inspector/InteractiveInspector';
2020

2121
import { InspectableViewModel } from '../../inspector/InspectableViewModel';
22+
import { waitFor } from '@testing-library/dom';
2223

2324
const fakeSessionContext = {
2425
session: {
@@ -151,17 +152,15 @@ it('closes the drawer on flip from open state', async () => {
151152
if (inspector) {
152153
inspector.flipDrawer();
153154
}
154-
await new Promise(resolve => setTimeout(resolve, 100));
155155
});
156156

157157
// react test renderer does not re-render the drawer component even if the
158158
// state is changed. Test the state change instead of DOM change.
159-
await act(async () => {
160-
const inspector = inspectorRef.current;
161-
if (inspector) {
162-
expect(inspector.state.drawerOpen).toBe(false);
159+
await waitFor(() => {
160+
const updatedInspector = inspectorRef.current;
161+
if (updatedInspector) {
162+
expect(updatedInspector.state.drawerOpen).toBe(false); // 确保抽屉被打开
163163
}
164-
await new Promise(resolve => setTimeout(resolve, 100));
165164
});
166165
});
167166

@@ -188,10 +187,11 @@ it('updates session info on change', async () => {
188187
fakeSessionContext.kernelDisplayName = 'new kernel';
189188
inspector.updateSessionInfo();
190189
}
191-
await new Promise(resolve => setTimeout(resolve, 100));
192190
});
193191

194-
const topAppBarHeader: Element =
195-
container.firstElementChild.firstElementChild.firstElementChild.children[1];
196-
expect(topAppBarHeader.innerHTML).toContain('Inspector [kernel:new kernel]');
192+
await waitFor(() => {
193+
const topAppBarHeader: Element =
194+
container.firstElementChild.firstElementChild.firstElementChild.children[1];
195+
expect(topAppBarHeader.innerHTML).toContain('Inspector [kernel:new kernel]');
196+
});
197197
});

sdks/python/apache_beam/runners/interactive/extensions/apache-beam-jupyterlab-sidepanel/src/__tests__/kernel/InterruptKernelButton.test.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import { act } from 'react';
1818

1919
import { InterruptKernelButton } from '../../kernel/InterruptKernelButton';
2020

21+
import { waitFor } from '@testing-library/react'
22+
2123
const fakeKernelModel = {
2224
isDone: true,
2325
interruptKernel: function (): void {
@@ -56,6 +58,7 @@ afterEach(async () => {
5658
it(`displays a button when the kernel model
5759
is not done with execution`, async () => {
5860
let button: InterruptKernelButton;
61+
5962
await act(async () => {
6063
root.render(
6164
<InterruptKernelButton
@@ -66,13 +69,19 @@ it(`displays a button when the kernel model
6669
/>
6770
);
6871
});
72+
6973
await act(async () => {
7074
fakeKernelModel.isDone = false;
7175
button?.updateRender();
7276
await new Promise(resolve => setTimeout(resolve, 100));
7377
});
78+
79+
await waitFor(() => {
80+
const button = container.firstElementChild;
81+
expect(button).not.toBeNull();
82+
expect(button?.tagName).toBe('BUTTON');
83+
})
7484
const buttonElement: null | Element = container.firstElementChild;
75-
expect(buttonElement.tagName).toBe('BUTTON');
7685
expect(buttonElement.getAttribute('class')).toContain('mdc-button');
7786
expect(buttonElement.getAttribute('class')).toContain('mdc-button--raised');
7887
const labelElement: Element = buttonElement.children[1];
@@ -92,7 +101,7 @@ it(`renders nothing when the kernel
92101

93102
it('interrupts the kernel when clicked', async () => {
94103
let button: InterruptKernelButton;
95-
const spiedInterrruptCall = jest.spyOn(fakeKernelModel, 'interruptKernel');
104+
const spiedInterruptCall = jest.spyOn(fakeKernelModel, 'interruptKernel');
96105
await act(async () => {
97106
root.render(
98107
<InterruptKernelButton
@@ -105,7 +114,8 @@ it('interrupts the kernel when clicked', async () => {
105114
});
106115
await act(async () => {
107116
button?.onClick();
108-
await new Promise(resolve => setTimeout(resolve, 100));
117+
await waitFor(() => {
118+
expect(spiedInterruptCall).toHaveBeenCalledTimes(1);
119+
});
109120
});
110-
expect(spiedInterrruptCall).toHaveBeenCalledTimes(1);
111121
});

0 commit comments

Comments
 (0)