3

I need to test a graphql-react component using @testing-library/react. I want to display text area based on a result value from query. [am able to get that]. But, unable to update the text area with the new value using @testing-library/user-event.

Here's the graphql-react component:

CustomWelcomeMessageContainer.jsx

import React from 'react';
import PropTypes from 'prop-types';
import {Query} from 'react-apollo';
import FormControl from "react-bootstrap/lib/FormControl";
import {FormSection, FormSectionItem} from "../../src/modules/Forms/components/FormSection/FormSection";
import get from "lodash/get";
import customWelcomeMessageQuery from "../../modules/Forms/queries/allowWelcomeMessageQuery";

const CustomWelcomeMessageContainer = ({isStudentBuddy, universitySlug, prospectWelcomeMessage, onProspectMessageChange}) => {
    return (<Query
                query={customWelcomeMessageQuery}
                variables={{
                    universitySlug,
                }}
    >
                {({loading, data}) => {
                    let allowWelcomeMessageCustomization;
                    if (isStudentBuddy) {
                        allowWelcomeMessageCustomization = get(
                            data,
                            "university.allowWelcomeMessageCustomization",
                        );
                    } else {
                        allowWelcomeMessageCustomization = get(
                            data,
                            "university.allowWelcomeMessageCustomizationStaff",
                        );
                    }
                    if (
                        !loading &&
                        allowWelcomeMessageCustomization
                    ) {
                        return (
        <FormSection header="Custom Welcome Message">
            <FormSectionItem>
                <FormControl
                    componentClass="textarea"
                    typeClass="text"
                    value={prospectWelcomeMessage}
                    placeholder="Enter text"
                    onChange={onProspectMessageChange}
                    required
                    rows={5}
                />
            </FormSectionItem>
        </FormSection>
    );
                    }

                    return null;
                }}
            </Query>
    );
};

CustomWelcomeMessageContainer.propTypes = {
    isStudentBuddy: PropTypes.bool,
    universitySlug: PropTypes.string.isRequired,
    prospectWelcomeMessage: PropTypes.string.isRequired,
    onProspectMessageChange: PropTypes.func.isRequired,
};


CustomWelcomeMessageContainer.defaultProps = {
    isStudentBuddy: false,
    userDetails: {},
};

export default CustomWelcomeMessageContainer;

This is the test file:

CustomWelcomeMessageContainer.test.jsx

import React from 'react';
import {render, screen} from '@testing-library/react';
import wait from 'waait';
import '@testing-library/jest-dom';
import userEvent from "@testing-library/user-event";
import {MockedProvider} from '@apollo/react-testing';
import CustomWelcomeMessageContainer from './CustomWelcomeMessageContainer';

const mocks = [{
    request: {
        query: customWelcomeMessageQuery,
        variables: {
            universitySlug: "staffTest1",
        },
    },
    result: {
        data: {
            university: {
                id: "staffTest1",
                allowWelcomeMessageCustomization: false,
                allowWelcomeMessageCustomizationStaff: true,
            },
        },
    },
},
];

describe('CustomWelcomeMessageContainer', async() => {
test("type", async () => {
        render(<textarea
            className="form-control"
            placeholder="Enter text"
            required=""
            rows="5"
            typeClass="text"
        >Hello world </textarea>);
        const val = await screen.findByRole("textbox");
        userEvent.clear(val);
  await userEvent.type(val, "hi");
  expect(val).toHaveValue("hi");
});

test('should display the value entered by the ambassador', async() => {
        render(
            <MockedProvider
                mocks={mocks}
                addTypename={false}
            >
                <CustomWelcomeMessageContainer
                    isStudentBuddy
                    universitySlug="studentTest1"
                    prospectWelcomeMessage="default"
                    onProspectMessageChange={jest.fn()}
                />
            </MockedProvider>,
        );
        await wait(0);
        const customWelcomeMessageTextBox = await screen.findByRole("textbox");
        userEvent.clear(customWelcomeMessageTextBox);
        await userEvent.type(customWelcomeMessageTextBox, "hi");
        expect(customWelcomeMessageTextBox).toHaveValue("hi");
    });
});

In the first test, a basic text area is rendered and the text update works successfully [which means there's no problem with the usage of user-event].

Whereas in the second test, the graphql-react component is rendered and the text update fails. Is it because the textarea is initially populated from the props? Unable to understand why the update doesn't work. This is the error I get:

Error: expect(element).toHaveValue(hi)

Expected the element to have value:
  hi
Received:
  default
Nick McCurdy
  • 17,658
  • 5
  • 50
  • 82
Ashwini
  • 381
  • 6
  • 23
  • does screen.findByRole return a valid component ? – prajnavantha May 14 '20 at 12:54
  • 1
    First check your roles to make sure there isn't a different textbox that you're picking up on accident. Just enter nonsense: "getByRole('blah')" then check the output to make sure to match the role of the element you are trying to get. – Devin Fields Oct 02 '20 at 17:31

1 Answers1

0

Try, this one.

const inputTextArea = getByRole("textbox");
expect(inputTextArea.value).toEqual("hi");
Hanoj B
  • 350
  • 2
  • 12