testcafe-react-selectors icon indicating copy to clipboard operation
testcafe-react-selectors copied to clipboard

How can I select components wrapped in ForwardRef with Material UI v4?

Open ShintaniWK opened this issue 5 years ago • 3 comments

I am troubled with the same problem as this article written in stackoverflow. https://stackoverflow.com/questions/55026027/how-can-i-select-components-wrapped-in-forwardref-with-material-ui-v4

I created the following component in Material-UI v4.1.2. I am in trouble because I can not select the elements below Drawer.

import Drawer from '@material-ui/core/Drawer';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';

function App() {
  return (
    <div className="App">
      <Drawer variant="permanent" anchor="left">
        <List>
          {['All mail', 'Trash', 'Spam'].map((text) => (
            <ListItem button key={text}>
              <ListItemText primary={text} />
            </ListItem>
          ))}
        </List>
      </Drawer>
    </div>
  );
}

Please tell me how to access Drawer or ListItem.

ShintaniWK avatar Jun 24 '19 02:06 ShintaniWK

I was able to reproduce the issue. However, at the moment, I cannot give any workarounds or estimates on when it will be fixed. This issue requires a lot of time for researching so please track this ticket to see the progress.

For the team.

import React from 'react';
import logo from './logo.svg';
import './App.css';

import Drawer from '@material-ui/core/Drawer';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';

const FancyButton = React.forwardRef(function btn (props, ref) {
    return (
        <button ref={ref} className="FancyButton">
            {props.children}
        </button>
    )
});

function App() {
    // You can now get a ref directly to the DOM button:
    const ref = React.createRef();
  return (
      <div className="App">
          <FancyButton ref={ref}>Click me!</FancyButton>
        <Drawer variant="permanent" anchor="left">
          <List>
            {['All mail', 'Trash', 'Spam'].map((text) => (
                <ListItem button key={text}>
                  <ListItemText primary={text} />
                </ListItem>
            ))}
          </List>
        </Drawer>
      </div>
  );
}

export default App
import { ReactSelector } from 'testcafe-react-selectors';
import { waitForReact } from 'testcafe-react-selectors';

fixture `TODO list test`
    .page('http://localhost:3000')
    .beforeEach(async () => {
        await waitForReact();
    });

test('', async t => {
    const el = ReactSelector('ForwardRef(btn)');

    await t.click(el);
});

AlexKamaev avatar Jun 25 '19 08:06 AlexKamaev

I think the challenge with this is the naming change when react-material-ui was updated. For example, I ran in a similar issue using TextField from material-ui. My test used to be ReactSelector('TextField'); but it had to change to ReactSelector('WithStyles(ForwardRef(TextField))'); because material-ui changed their naming.

So the limitation is using string to get the React component in ReactSelector. You would have control over the naming of it if it is your own component but when using a third-party library your tests will break whenever they change the naming.

One fix for that could be to pass the component down to theReactSelector i.e.:

import { ReactSelector } from 'testcafe-react-selectors';
import TextField from '@material-ui/core/TextField';

fixture `TODO list test`
    .page('http://localhost:3000')
    .beforeEach(async () => {
        await waitForReact();
    });

test('', async t => {
    const el = ReactSelector(TextField);

    await t.click(el);
});

What do you think?

zsid avatar Jul 08 '19 14:07 zsid

Thank you for providing us with additional details and for sharing ideas concerning the implementation! On the one hand, passing the component's constructor instead of its name into the ReactSelector function is clear in terms of API. On the other hand, the context in which TestCafe executes a test doesn't match the browser context, so it will be impossible to compare it with something on the client side directly. Our team will need time to research this issue in detail. Your patience is greatly appreciated.

arubtsov avatar Jul 10 '19 08:07 arubtsov

This issue has been automatically marked as stale because it has not had any activity for a long period. It will be closed and archived if no further activity occurs. However, we may return to this issue in the future. If it still affects you or you have any additional information regarding it, please leave a comment and we will keep it open.

github-actions[bot] avatar Dec 10 '22 01:12 github-actions[bot]

We're closing this issue after a prolonged period of inactivity. If it still affects you, please add a comment to this issue with up-to-date information. Thank you.

github-actions[bot] avatar Dec 20 '22 01:12 github-actions[bot]