英文:
How do I use data-testid attribute with a React Component Test?
问题
I am doing a Component Test on a simple react component, which I want to render and then do some tests on.
The problem is that cy.get()
does not seem to find the component based on a data-testid
attribute.
I tested it with a simple div
and the div
can be found just fine.
I also noticed when inspecting the DOM
in the cypress runner, that the Component is not being rendered, but the contents of it are. Basically there is no <MockComponent>
it.only("renders and finds Component", () => {
cy.mount(
<ApolloProvider client={client}>
<MockComponent data-testid='mock-component' {...someData} />
<div data-testid='my-div'></div>
</ApolloProvider>
);
cy.get("[data-testid='my-div']").should('exist'); //this works
cy.get("[data-testid='mock-component']").should('exist'); //this doesn't
});
How can I get the <MockComponent>
in cypress, so that I can run tests on it?
英文:
I am doing a Component Test on a simple react component, which I want to render and then do some tests on.
The problem is that cy.get()
does not seem to find the component based on a data-testid
attribute.
I tested it with a simple div
and the div
can be found just fine.
I also noticed when inspecting the DOM
in the cypress runner, that the Component is not being rendered, but the contents of it are. Basically there is no <MockComponent>
it.only("renders and finds Component", () => {
cy.mount(
<ApolloProvider client={client}>
<MockComponent data-testid='mock-component' {...someData} />
<div data-testid='my-div'></div>
</ApolloProvider>
);
cy.get("[data-testid='my-div']").should('exist'); //this works
cy.get("[data-testid='mock-component']").should('exist'); //this doesn't
});
How can I get the <MockComponent>
in cypress, so that I can run tests on it?
答案1
得分: 6
以下是您要翻译的内容:
You can't add data-id attributes directly to the React component and have it appear on the DOM content.
All attributes (data or otherwise) that you put on MockComponent
are passed in as props to your component. This is standard for React.
So, if you examine props
inside MockComponent
, it will have a property named data-testid
with a value of mock-component
.
You will have to convert that into an attribute inside MockComponent
, on one of it's rendered elements.
Note that MockComponent
never appear in the DOM, just it's rendered children.
For example, explicitly:
const MockComponent = (props) => {
return (
<div data-testid={props["data-testid"]}>
<span>this is mock component</span>
</div>
)
}
...
cy.get("[data-testid='mock-component']") // passes
The <div>
inside MockComponent's return value is the "outer" element rendered to DOM, so that's where you need the data-id.
Or you can do it implicitly. Since someData
is part of your component API, you can split it off and assume the remainder will be utilized as attributes (without actually knowing what they are).
const MockComponent = (props) => {
const { someData, ...rest } = props;
const [data, setData] = useState(someData);
return (
<div {...rest}>
<span>this is mock component</span>
</div>
)
}
...
cy.get("[data-testid='mock-component']") // passes
One more way is to add a child to MockComponent
, which must be a real element.
All child elements are passed as props.children
, and you must render them inside the return value.
const MockComponent = (props) => {
const { someData } = props;
const [data, setData] = useState(someData);
return (
<div>
<span>this is mock component</span>
{props.children}
</div>
)
}
...
cy.mount(
<MockComponent {...someData} >
<span data-testid='mock-component-child' ></span>
</MockComponent>
);
cy.get("[data-testid='mock-component-child']") // passes
.parent() // outer element of MockComponent
英文:
You can't add data-id attributes directly to the the React component and have it appear on the DOM content.
All attributes (data or otherwise) that you put on MockComponent
are passed in as props to your component. This is standard for React.
So, if you examine props
inside MockComponent
, it will have a property named data-testid
with a value of mock-component
.
You will have to convert that into an attribute inside MockComponent
, on one of it's rendered elements.
Note that MockComponent
never appear in the DOM, just it's rendered children.
For example, explicitly:
const MockComponent = (props) => {
return (
<div data-testid={props["data-testid"]}>
<span>this is mock component</span>
</div>
)
}
...
cy.get("[data-testid='mock-component']") // passes
The <div>
inside MockComponent's return value is the "outer" element rendered to DOM, so that's where you need the data-id.
Or you can do it implicitly. Since someData
is part of your component API, you can split it off and assume the remainder will be utilized as attributes (without actually knowing what they are).
const MockComponent = (props) => {
const {someData, ...rest} = props;
const [data, setData] = useState(someData);
return (
<div {...rest}>
<span>this is mock component</span>
</div>
)
}
...
cy.get("[data-testid='mock-component']") // passes
One more way is to add a child to MockComponent
, which must be a real element.
All child elements are passed as props.children
, and you must render them inside the return value.
const MockComponent = (props) => {
const {someData} = props
const [data, setData] = useState(someData);
return (
<div>
<span>this is mock component</span>
{props.children}
</div>
)
}
...
cy.mount(
<MockComponent {...someData} >
<span data-testid='mock-component-child' ></span>
</MockComponent>
);
cy.get("[data-testid='mock-component-child']") // passes
.parent() // outer element of MockComponent
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论