RTL 中的 waitForElementToBeRemoved 错误超时
Timed out in waitForElementToBeRemoved error in RTL
我有一个使用 Formik 制作的基本登录表单,只是想写一个 RTL 和笑话代码来填写详细信息,提交表单,然后导航到 主页。因此,写成如下:
it('Fill the form and login', async () => {
render(<Login />)
await userEvent.type(screen.getByTestId('emailInput'), 'neeraj@gmail.com')
await userEvent.type(screen.getByTestId('passwordInput'), 'neeraj')
await userEvent.click(screen.getByTestId('submitBtn'))
expect(window.location.pathname).toBe('/')
})
以上测试已通过,但出现经典 act 错误。
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
因此,参考此 blog post 并按照建议使用 waitForElementToBeRemoved 函数,但现在测试因超时错误而失败。
使用 waitForElementToBeRemoved 更新了测试用例
it('Fill the form and login', async () => {
render(<Login />)
await userEvent.type(screen.getByTestId('emailInput'), 'neeraj@gmail.com')
await userEvent.type(screen.getByTestId('passwordInput'), 'neeraj')
await userEvent.click(screen.getByTestId('submitBtn'))
expect(window.location.pathname).toBe('/')
await waitForElementToBeRemoved(screen.getByTestId('emailInput'))
})
错误:
Timed out in waitForElementToBeRemoved.
Ignored nodes: comments, <script />, <style />
<html>
<head />
<body>
<div>
<div>
<div
data-testid="loginCard"
>
<form
data-testid="loginForm"
>
<div>
<label
for="email-input"
>
Email
</label>
<input
data-testid="emailInput"
id="email-input"
name="email"
type="email"
value="neeraj@gmail.com"
/>
</div>
<div>
<label
for="pass-input"
>
Password
</label>
<input
data-testid="passwordInput"
id="pass-input"
name="password"
type="password"
value="neeraj"
/>
</div>
<button
data-testid="submitBtn"
type="submit"
>
Submit
</button>
</form>
</div>
</div>
</div>
</body>
</html>
19 |
20 | expect(window.location.pathname).toBe('/')
> 21 | await waitForElementToBeRemoved(screen.getByTestId('emailInput'))
| ^
22 | })
23 | })
24 |
at waitForElementToBeRemoved (node_modules/@testing-library/dom/dist/wait-for-element-to-be-removed.js:22:24)
at Object.<anonymous> (tests/login.test.js:21:11)
试图将这三个 userEvent 包装在 act 函数中,但出现相同的超时错误,无法弄清楚我在哪里出错了。
我成功通过了测试用例,没有行为警告。
由于您在用户单击 submitBtn
按钮时调用异步函数 setTimeout,因此您必须等待承诺解决。
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import React from 'react'
import Login from './../pages/login'
describe('Login Page', () => {
it('renders without crashing', () => {
render(<Login />)
expect(screen.getByTestId('loginCard')).toBeInTheDocument()
})
it('Fill the form and login', async () => {
render(<Login />)
userEvent.type(screen.getByLabelText(/email/i), 'neeraj@gmail.com')
userEvent.type(screen.getByLabelText(/password/i), 'neeraj')
userEvent.click(screen.getByTestId('submitBtn'))
await waitFor(() => expect(window.location.pathname).toBe('/'))
})
})
您也可以对单击事件使用异步操作来完成此操作,该事件将等待解决承诺并完成状态更新。
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import React from 'react'
import Login from './../pages/login'
describe('Login Page', () => {
it('renders without crashing', () => {
render(<Login />)
expect(screen.getByTestId('loginCard')).toBeInTheDocument()
})
it('Fill the form and login', async () => {
render(<Login />)
userEvent.type(screen.getByLabelText(/email/i), 'neeraj@gmail.com')
userEvent.type(screen.getByLabelText(/password/i), 'neeraj')
await act(async () => userEvent.click(screen.getByTestId('submitBtn')))
expect(window.location.pathname).toBe('/')
})
})
我有一个使用 Formik 制作的基本登录表单,只是想写一个 RTL 和笑话代码来填写详细信息,提交表单,然后导航到 主页。因此,写成如下:
it('Fill the form and login', async () => {
render(<Login />)
await userEvent.type(screen.getByTestId('emailInput'), 'neeraj@gmail.com')
await userEvent.type(screen.getByTestId('passwordInput'), 'neeraj')
await userEvent.click(screen.getByTestId('submitBtn'))
expect(window.location.pathname).toBe('/')
})
以上测试已通过,但出现经典 act 错误。
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
因此,参考此 blog post 并按照建议使用 waitForElementToBeRemoved 函数,但现在测试因超时错误而失败。
使用 waitForElementToBeRemoved 更新了测试用例
it('Fill the form and login', async () => {
render(<Login />)
await userEvent.type(screen.getByTestId('emailInput'), 'neeraj@gmail.com')
await userEvent.type(screen.getByTestId('passwordInput'), 'neeraj')
await userEvent.click(screen.getByTestId('submitBtn'))
expect(window.location.pathname).toBe('/')
await waitForElementToBeRemoved(screen.getByTestId('emailInput'))
})
错误:
Timed out in waitForElementToBeRemoved.
Ignored nodes: comments, <script />, <style />
<html>
<head />
<body>
<div>
<div>
<div
data-testid="loginCard"
>
<form
data-testid="loginForm"
>
<div>
<label
for="email-input"
>
Email
</label>
<input
data-testid="emailInput"
id="email-input"
name="email"
type="email"
value="neeraj@gmail.com"
/>
</div>
<div>
<label
for="pass-input"
>
Password
</label>
<input
data-testid="passwordInput"
id="pass-input"
name="password"
type="password"
value="neeraj"
/>
</div>
<button
data-testid="submitBtn"
type="submit"
>
Submit
</button>
</form>
</div>
</div>
</div>
</body>
</html>
19 |
20 | expect(window.location.pathname).toBe('/')
> 21 | await waitForElementToBeRemoved(screen.getByTestId('emailInput'))
| ^
22 | })
23 | })
24 |
at waitForElementToBeRemoved (node_modules/@testing-library/dom/dist/wait-for-element-to-be-removed.js:22:24)
at Object.<anonymous> (tests/login.test.js:21:11)
试图将这三个 userEvent 包装在 act 函数中,但出现相同的超时错误,无法弄清楚我在哪里出错了。
我成功通过了测试用例,没有行为警告。
由于您在用户单击 submitBtn
按钮时调用异步函数 setTimeout,因此您必须等待承诺解决。
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import React from 'react'
import Login from './../pages/login'
describe('Login Page', () => {
it('renders without crashing', () => {
render(<Login />)
expect(screen.getByTestId('loginCard')).toBeInTheDocument()
})
it('Fill the form and login', async () => {
render(<Login />)
userEvent.type(screen.getByLabelText(/email/i), 'neeraj@gmail.com')
userEvent.type(screen.getByLabelText(/password/i), 'neeraj')
userEvent.click(screen.getByTestId('submitBtn'))
await waitFor(() => expect(window.location.pathname).toBe('/'))
})
})
您也可以对单击事件使用异步操作来完成此操作,该事件将等待解决承诺并完成状态更新。
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import React from 'react'
import Login from './../pages/login'
describe('Login Page', () => {
it('renders without crashing', () => {
render(<Login />)
expect(screen.getByTestId('loginCard')).toBeInTheDocument()
})
it('Fill the form and login', async () => {
render(<Login />)
userEvent.type(screen.getByLabelText(/email/i), 'neeraj@gmail.com')
userEvent.type(screen.getByLabelText(/password/i), 'neeraj')
await act(async () => userEvent.click(screen.getByTestId('submitBtn')))
expect(window.location.pathname).toBe('/')
})
})