Recently I came across the requirement to add additional classNames to components so the QA team could use Selenium to test our app.

I had two requirements for adding these:

  1. I didn’t want to go through the complete codebase to give all components some recognizable class
  2. I wanted the additional classes to be gone in production so my output remains clean

 

The way I achieved that was to intercept the render method call. It was more difficult because of the way that browserify packages modules so I could not get to ReactCompositeComponent before it was mixed into a wrapper and had to modify it through a detour. Here’s the code. Just require it in your project and it should register itself.

const instantiateReactComponent = require('react/lib/instantiateReactComponent');

// intercept all render calls
if (process.env.NODE_ENV !== 'production') {
  const instance = instantiateReactComponent({ type: 'InterceptRender' });
  const oldRender = instance.constructor.prototype._renderValidatedComponentWithoutOwnerOrContext;
  instance.constructor.prototype._renderValidatedComponentWithoutOwnerOrContext = function interceptRender() {
    // before render: this._instance is the instance
    const renderedComponent = oldRender.apply(this);
    // after render
    return renderedComponent;
  };
}

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.