2

I am struggling to understand why this component doesn't update after I click on it with userEvent. I have a search bar, when focused === true, it expands, and has another field "Move in". This is my test that doesn't work and I don't get the search bar expanded after clicking.

describe("Searchbar tests", () => {
  let SearchBar = (
    <DesktopSearch
      wrapper={wrap}
      handleKeyDown={jest.fn()}
      handleChange={jest.fn()}
      availability={undefined}
    />
  );

  it("should have move in once focused", async () => {
    render(SearchBar);
    const searchDiv = await screen.findByTestId("search-location");
    await userEvent.click(searchDiv);
    expect(screen.getByText("Move in")).toBeInTheDocument();
  });
});

screen.debug()

  <body>
      <div>
        <div
          class="sc-ksdxgE cXdeLl"
        >
          <div
            class="sc-hBUSln bQqsgK"
            data-testid="search-location"
          >
            <span
              style="width: 0px; opacity: 0;"
            >
              Search
            </span>
            <div>
              <span
                style="line-height: 0.5;"
              >
                Location
              </span>
              <input
                class="sc-fotOHu bfsfMe"
                value=""
              />
            </div>
            <div
              class="sc-fFeiMQ htNsUj"
              style="width: 6.49676%;"
            />
          </div>
          <svg
            class="sc-kfPuZi kGORHg"
            fill="currentColor"
            height="20"
            stroke="currentColor"
            stroke-width="0"
            viewBox="0 0 16 16"
            width="20"
            xmlns="http://www.w3.org/2000/svg"
          >
            <title>
              Search
            </title>
            <path
              d="M15.7 13.3l-3.81-3.83A5.93 5.93 0 0 0 13 6c0-3.31-2.69-6-6-6S1 2.69 1 6s2.69 6 6 6c1.3 0 2.48-.41 3.47-1.11l3.83 3.81c.19.2.45.3.7.3.25 0 .52-.09.7-.3a.996.996 0 0 0 0-1.41v.01zM7 10.7c-2.59 0-4.7-2.11-4.7-4.7 0-2.59 2.11-4.7 4.7-4.7 2.59 0 4.7 2.11 4.7 4.7 0 2.59-2.11 4.7-4.7 4.7z"
              fill-rule="evenodd"
            />
          </svg>
        </div>
      </div>
    </body>

Minimal example:

    import { SearchBarContext } from "context";
import { AnimatePresence, AnimateSharedLayout, motion } from "framer-motion";
import { ReactElement, useContext } from "react";
import { DeviceSearchProps } from ".";
import {
  AutocompleteContainer,
  SearchAvailability,
  SearchDate,
  SearchIcon,
  SearchInput,
  SearchLocation,
  SearchStyle,
} from "./desktopStyles";

    export default function DesktopSearch({
      className,
      wrapper,
      handleKeyDown: _handleKeyDown,
      handleChange: _handleChange,
      availability,
    }: DeviceSearchProps): ReactElement {
      const { focus, focused } = useContext(SearchBarContext);
      // [focused, setFocused] = useState(false),
      //focus = () => setFocused(true),
    
      return (
        <SearchStyle className={className} ref={wrapper}>
          <AnimateSharedLayout>
            <SearchLocation onClick={focus} layout>
              <AnimatePresence>
                <motion.span
                  initial={{ width: "0px" }}
                  animate={{
                    width: focused ? "0px" : "auto",
                    opacity: focused ? 0 : 1,
                  }}
                  transition={{ duration: 0.5, type: "string", delay: 0.2 }}
                >
                  Search
                </motion.span>
              </AnimatePresence>
              <div>
                <span style={{ lineHeight: 0.5 }}>Location</span>
                <SearchInput isFocused={focused} />
              </div>
              <AutocompleteContainer
                animate={{ width: focused ? "110%" : "90%" }}
                transition={{ duration: 0.2, type: "string" }}
              ></AutocompleteContainer>
            </SearchLocation>
    
            {focused && (
              <>
                <SearchDate>
                  <SearchAvailability
                    initial={{ opacity: 0 }}
                    animate={{ opacity: 1 }}
                    exit={{ opacity: 0 }}
                  >
                    {availability ? (
                      availability.toLocaleDateString("en-GB")
                    ) : false ? (
                      <>__ __ __</>
                    ) : (
                      "Move in"
                    )}
                  </SearchAvailability>
                </SearchDate>
              </>
            )}
            <SearchIcon size={20} />
          </AnimateSharedLayout>
        </SearchStyle>
      );

}
9
  • Could you please call screen.debug() after clicking on the element and attach the result to your question? Commented Jun 14, 2022 at 9:07
  • Without a minimal reproducible example including a minimal component, it's very hard to say. Commented Jun 14, 2022 at 10:04
  • I don't think <div /> element can be focused without specifying tabindex to it. Or, as an alternative, you can assign data-testid="search-location" attribute to input element within the "search location" block Commented Jun 14, 2022 at 10:09
  • Hey! Did you try to know is when doing the userEvent is really focused? Check this testing-library.com/docs/guide-events/#focusblur Commented Jun 14, 2022 at 10:29
  • 1
    @illyria, I may also assume that it doesn't work with context, because the context doesn't exist when you render the component with react testing library. Try to add a wrapper to the render function to wrap the component by the context - render(SearchBar, {wrapper: SearchBarContext.Provider}) Commented Jun 14, 2022 at 12:47

2 Answers 2

2

The problem in this code is that the context doesn't exist when you render the component with react testing library. Try to add a wrapper to the render function to wrap the component by the context

const WithContextProviders = ({ children }) => {
  return (
    <SearchBarContext.Provder {...providersPropsIfNeeded}>
      {children}
    </SearchBarContext.Provder>
  );
};

it("should have move in once focused", async () => {
  render(SearchBar, { wrapper: WithContextProviders });
  const searchDiv = await screen.findByTestId("search-location");
  await userEvent.click(searchDiv);
  expect(screen.getByText("Move in")).toBeInTheDocument();
});
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you for your answer. I tried both, and it still doesn't work. I get the same screen.debug()
Can you also attach the implementation of the component so we can reproduce this problem?
The component is quite big, and takes props from other components, and uses useContext. I am not sure I can post all you'd need
You can post a minimal example that reproduces the same problem
I edited again the main post with it
|
0

Since I do not know how you handle the focus === true I've created a little example that maybe helps you:

I handle if is focused or not with a useState by default false and then when, in that case the button, is clicked changes to true Move in is displayed

import { useState } from "react";

function App() {
  const [isFocus, setIsFocus] = useState(false);

  const handleFocus = () => {
    setIsFocus(true);
  };

  return (
    <>
      <button onClick={handleFocus}>Display text when clicked</button>
      {isFocus ? <p>Move in</p> : ""}
    </>
  );
}  
export default App;

And this is the test, that passes:

test("focus should render", async () => {
  render(<App />);

  expect(screen.queryByText(/Move in/i)).not.toBeInTheDocument();

  fireEvent.click(screen.getByText(/Display text when clicked/i));
  expect(screen.getByText(/Move in/i)).toBeInTheDocument();
});

enter image description here

8 Comments

Hey @S.Marx, I updated the question with the component, but either way, focus is just setFocused(true). I tried your code, but it doesn't work
How do you handle when is focused or not in your code?
it's just a usestate, defaulted to false, when I click it becomes true
How weird, it should work. Or add some moe code sho we can see
The issue apparently is the useContext. I changed focus and focused with local states there and it works. I guess I need to understand how to make it work with useContext. Thank you!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.