DevExpress / testcafe-react-selectors

TestCafe selector extensions for React apps.
https://testcafe.io
MIT License
205 stars 43 forks source link

Cannot get OpenLayer React component: getReact cannot return DOM elements. #165

Closed xmarduel closed 4 years ago

xmarduel commented 4 years ago

ReactSelector works perfectly well. But for a standard react component used to display an openlayers map, the "getReact()" method return the error message 1) getReact cannot return DOM elements. Use Selector functions for this purpose. The standard way to use openlayerwith react is the following:

  1. the render function only declares a "container"
    render() {
    return (
      <div id="mapContainer" ref="mapContainer"/>
    );
    } 

and the openlayers map is created in the componentDidMount()method, giving theol Map constructor the "target""mapContainer":

import Map from "ol/Map";
import View from "ol/View";

class OLMapReact  extends Component {
  constructor(props) {
    super(props);

    // of course I want the react component to have a pointer on the ol map
    this.map = null;

    this.state = {
      map   : this.map,
    }
  }

  componentDidMount() {
    this.map = new Map({
      layers: [],  // add layers later....
      target: 'mapContainer',
      view: new View({
        center: [-0.0, 0.0],
        zoom: 13
      })
   });

    // save map in state
    this.setState({
      map: this.map,
    });
  }

  // pass new features from props into the OpenLayers layer object
  componentDidUpdate(prevProps, prevState) {}

  render() {
    return (
      <div id="mapContainer" ref="mapContainer"/>
    );
  }
}

export default OLMapReact;
My test is also trivial, from javascript 👍 

import { Selector } from 'testcafe';

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

fixture `T1`
    .page `http://localhost:3000/app_with_openlayers`
    .beforeEach(async () => {
        await waitForReact();
    });

test('Test OLMap', async t => {
    const AppSelector = ReactSelector('App');
    console.log("***AppSelector***");
    //console.log(AppSelector);
    const AppComponent = await AppSelector.getReact();
    console.log(AppComponent);
    console.log(AppComponent.state);  // OK!

    const OLMapReactSelector = ReactSelector('OLMapReact');
    console.log("***OLMapReactSelector***");  // Selector seems OK! 
    console.log(OLMapReactSelector);           // Selector seems OK! 
    const OLMapReactComponent =  await OLMapReactSelector.getReact();
    if ( OLMapReactComponent !== null ) {
        console.log(OLMapReactComponent.state);
    }
    else {
        // it goes here !!
        console.log("#######OL MapReactComponent null ######");
    }

    await t
        console.log("***OLMapReact***");
});

So yes, in the test, after I would like to have apointer on the real openlayers map instance

npx testcafe "chrome:headless" src\test\testcafe\react\test\TestMap.js

Another question: how to use the ReactSelector inside the TestCafe Studio ?

Thanks in advance.

miherlosev commented 4 years ago

Hi @xmarduel

The getReact method returns only serialized objects. It looks like state.map contains a DOM element, which cannot be serialized. You need to filter the React component properties that you want to check in a test using the following predicate: .getReact( ({ props, state, key }) => ). See an example of how to do this in here.

how to use the ReactSelector inside the TestCafe Studio?

See detailed instructions here.