• 카테고리

    질문 & 답변
  • 세부 분야

    프론트엔드

  • 해결 여부

    해결됨

This could be because the text is broken up by multiple elements. 에러

23.03.21 23:04 작성 23.03.21 23:06 수정 조회수 858

0

선생님 안녕하세요

아무리 봐도 오류 이유를 모르겠어서 질문드립니다.

제 오류는 아래와 같습니다. (코드상 에러난 부분 ✅ 했습니다)

> TestingLibraryElementError: Unable to find an element with the text: /loading/i. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

 

// CompletePage.js

import axios from "axios";
import React, { useEffect, useContext, useState } from "react";
import ErrorBanner from "../../components/ErrorBanner";
import { OrderContext } from "../../contexts/OrderContext";

function CompletePage({ setStep }) {
  const [OrderDatas, , resetOrderDatas] = useContext(OrderContext);
  const [orderHistory, setOrderHistory] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);
  useEffect(() => {
    orderCompleted(OrderDatas);
  }, [OrderDatas]);

  const orderCompleted = async (OrderDatas) => {
    try {
      let response = await axios.post(
        "http://localhost:5001/order",
        OrderDatas
      );
      setOrderHistory(response.data);
      setLoading(false);
    } catch (error) {
      setError(true);
    }
  };

  if (error) {
    return <ErrorBanner message="에러가 발생했습니다." />;
  }

  const orderTable = orderHistory.map((item) => (
    <tr key={item.orderNumber}>
      <td>{item.orderNumber}</td>
      <td>{item.price}</td>
    </tr>
  ));

  const handleClick = () => {
    resetOrderDatas();
    setStep(0);
  };

  if (loading) {
    return <div>loading</div>; ✅
  } else {
    return (
      <div style={{ textAlign: "center" }}>
        <h2>주문이 성공했습니다.</h2>
        <h3>지금까지 모든 주문</h3>
        <table style={{ margin: "auto" }}>
          <thead>
            <tr>
              <th>주문 번호</th>
              <th>주문 가격</th>
            </tr>
          </thead>
          <tbody>{orderTable}</tbody>
        </table>
        <button onClick={handleClick}>첫페이지로</button>
      </div>
    );
  }
}

export default CompletePage;
//App.test.js
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import App from "./App";

test("From order to order completion", async () => {
  render(<App />);

  const event = userEvent.setup();
  const americaInput = await screen.findByRole("spinbutton", {
    name: "America",
  });
  await event.clear(americaInput);
  await event.type(americaInput, "2");

  // England 여행 상품 3개 추가합니다.
  const englandInput = await screen.findByRole("spinbutton", {
    name: "England",
  });
  await event.clear(englandInput);
  await event.type(englandInput, "3");

  // insurance 옵션체크

  const insuranceCheckbox = await screen.findByRole("checkbox", {
    name: "Insurance",
  });

  await event.click(insuranceCheckbox);

  //모든 주문을 한 이후 주문 버튼 클릭!
  const orderButton = screen.getByRole("button", {
    name: "주문",
  });
  await event.click(orderButton);

  //////////   주문확인페이지    ///////
  const summaryHeading = screen.getByRole("heading", { name: "주문 확인" });
  expect(summaryHeading).toBeInTheDocument();

  const productHeading = screen.getByRole("heading", {
    name: "여행 상품: 5000",
  });
  expect(productHeading).toBeInTheDocument();

  const optionsHeading = screen.getByRole("heading", {
    name: "옵션: 500",
  });
  expect(optionsHeading).toBeInTheDocument();

  expect(screen.getByText("2 America")).toBeInTheDocument();
  expect(screen.getByText("3 England")).toBeInTheDocument();
  expect(screen.getByText("Insurance")).toBeInTheDocument();

  const confirmCheckbox = screen.getByRole("checkbox", {
    name: "주문하려는것을 확인 하셨나요?",
  });
  await event.click(confirmCheckbox);

  const confirmOrderButton = screen.getByRole("button", {
    name: "주문 확인",
  });
  await event.click(confirmOrderButton);

  //// 주문 완료 ////
  const loading = screen.getByText(/loading/i); ✅ 
  expect(loading).toBeInTheDocument();

  const completeHeader = await screen.findByRole("heading", {
    name: "주문이 성공했습니다.",
  });
  expect(completeHeader).toBeInTheDocument();

  const loadingDisappeared = screen.queryByText("loading");
  expect(loadingDisappeared).not.toBeInTheDocument();

  const firstPageButton = screen.getByRole("button", {
    name: "첫페이지로",
  });
  event.click(firstPageButton);

  const productsTotal = screen.getByText("상품 총 가격: 0");
  expect(productsTotal).toBeInTheDocument();

  const optionsTotal = screen.getByText("옵션 총 가격: 0");
  expect(optionsTotal).toBeInTheDocument();

  await waitFor(() => {
    screen.getByRole("spinbutton", { name: "America" });
  });
});

스크린샷 2023-03-21 오후 10.10.34.jpg

제가 에러를 이해한 바로는 return 문이 여러 경우로 나뉘어서 그렇다고 생각했습니다. 제대로 이해한게 맞을까요..?( This could be because the text is broken up by multiple elements.)

실제로 아래 else return문에 loading을 넣어주니 해결이 되긴 했습니다. 하지만 아래 ✅와 같이 작성해주면 에러가 뜨네요..

왜 이러는건지 혹시 아실까요? ㅠㅠ

if (loading) {
    return <div>loading</div>; ✅
  } else {
    return (
      <div style={{ textAlign: "center" }}>
        <h2>주문이 성공했습니다.</h2>
        <h3>지금까지 모든 주문</h3>
        <table style={{ margin: "auto" }}>
          <thead>
            <tr>
              <th>주문 번호</th>
              <th>주문 가격</th>
            </tr>
          </thead>
          <tbody>{orderTable}</tbody>
        </table>
        <button onClick={handleClick}>첫페이지로</button>
      </div>
    );
  }

선생님 코드를 보고 복붙했는데도 해결이 안되네요.ㅜ

 

 

답변 2

·

답변을 작성해보세요.

1

소스 코드를 보니깐

  const orderCompleted = async (OrderDatas) => {
    try {
      let response = await axios.post(
        "http://localhost:5001/order",
        OrderDatas
      );
      setOrderHistory(response.data);
      // setLoading(false);
    } catch (error) {
      setError(true);
    }
  };

여기에서 setLoading을 주석 처리하면
그 부분 에러가 없어지더라구요.


act(() => {

/* fire events that update state */

});

/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act

at App (/Users/johnahn/Desktop/react-test-code-practice-main/src/App.js:8:35)

at OrderContextProvider (/Users/johnahn/Desktop/react-test-code-practice-main/src/contexts/OrderContext.js:19:49)

33 | const handleSubmit = (e) => {

34 | e.preventDefault();

> 35 | setStep(2);

| ^

36 | };

37 | return (

38 | <div>

현재 보면 이런 식으로 에러가 많이 나는데

혹시 강의 들으시다가 언제부터 이렇게 나는지 아시나요?

그 부분부터 에러를 해결해나가야 할 것 같습니다 ~!


그리고 axios 에러 나서 버전 다운그레이드 하신것 같은데

원래 버전 설치하시고

"jest": { "moduleNameMapper": { "axios": "axios/dist/node/axios.cjs" } },

이 부분을 package.json 파일 부분에 넣어주시면 됩니다 ~

sos님의 프로필

sos

질문자

2023.03.27

선생님 해결했습니다!!! 😭

선생님이 말씀하신 에러 해결이 먼저였고, 그걸 해결하니 자연스레 다른 오류들도 해결되었습니다.

https://github.com/testing-library/user-event/issues/1107 이 글을 참고할 수 있었는데요.

참고한 결과, 저 에러들의 오류는 패키지 락 제이슨의 @testing-library/dom 버전에의한 버그로 보여집니다. (현재 해결중인것같아요)

글에서 참고한 바와 같이 "8.20.0" 버전으로 변경해주면 잘 돌아갑니다.

@testing-library/dom : {
    version: "8.20.0"
}

 

오류 봐주셔서 정말 감사합니다!

 

 

스크린샷 2023-03-25 오후 3.27.44.jpg

아 너무 수고하셨습니다!!

1

안녕하세요!

혹시 저장소 주소 주실 수 있을까요?!

제가 직접 해보겠습니다 ~

sos님의 프로필

sos

질문자

2023.03.22

여기 있습니다!

참고로 서버 포트는5001로 지정했습니다.