Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove warnings when rendering react-native components #831

Closed
jsdario opened this issue Feb 27, 2017 · 19 comments
Closed

Remove warnings when rendering react-native components #831

jsdario opened this issue Feb 27, 2017 · 19 comments

Comments

@jsdario
Copy link

jsdario commented Feb 27, 2017

Hi, I have been struggling to properly test react-native components, so I resigned to mount them and I am currently testing them only on shallow or render methods. I opened a stackoverflow question in case someone can help in this matter.

However on every test I get a long list of warnings (printed with console.error, but not crashing the test), about the properties that are expected / received:

Ran all test suites matching "app/components/__tests__/components-test.js".
  console.error node_modules/react-native/Libraries/Core/ExceptionsManager.js:71
    Warning: In next release empty section headers will be rendered. In this release you can use 'enableEmptySections' flag to render empty section headers.

  console.error node_modules/react-native/Libraries/Core/ExceptionsManager.js:71
    Warning: Unknown props `refreshControl`, `renderRow`, `renderHeader`, `renderFooter`, `dataSource`, `initialListSize`, `pageSize`, `scrollRenderAheadDistance`, `onEndReachedThreshold`, `stickyHeaderIndices`, `scrollEventThrottle`, `removeClippedSubviews`, `onKeyboardWillShow`, `onKeyboardWillHide`, `onKeyboardDidShow`, `onKeyboardDidHide`, `onContentSizeChange`, `onLayout` on <ScrollView> tag. Remove these props from the element. For details, see https://fb.me/react-unknown-prop
        in ScrollView (created by ScrollView)
        in ScrollView (created by ListView)
        in ListView (created by DynGridLayout)
        in DynGridLayout
        in Provider

I would like to remove such warnings or have a resource I can follow to properly test react-native components on Jest

@yesmeck
Copy link
Contributor

yesmeck commented Mar 1, 2017

I think you can not use render to react-native components, see https://github.com/airbnb/enzyme/blob/master/docs/guides/react-native.md

@jsdario
Copy link
Author

jsdario commented Mar 1, 2017

With shallow it does not prompt warnings, and it does work with render (so tests are working). However they cannot yet be used with mount (I believe) because of the Native DOM.

It would be great –even if a workaround– to remove such logs.

@ThaJay
Copy link

ThaJay commented May 23, 2017

Even with shallow() I have one warning:

    console.error node_modules/react-native/Libraries/Core/ExceptionsManager.js:71
      Warning: ReactTestUtils has been moved to react-dom/test-utils. Update references to remove this warning.

Why would I need react-dom when I use react-native?

edit: even after installing react-dom it gives the same warning

@ljharb
Copy link
Member

ljharb commented Jul 25, 2017

#1007 will be the solution to this.

@Meligy
Copy link

Meligy commented Nov 25, 2017

I also had the same issue with shallow().

I cloned https://github.com/Microsoft/TypeScript-React-Native-Starter and upgraded all dev packages.

I then did the setup for React 16:

import * as enzyme from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';

enzyme.configure({
    adapter: new Adapter(),
});

And ran jest with the simple test that came with the repo.

import * as React from 'react';
import { Text } from 'react-native';
import { shallow } from 'enzyme';

import Hello from '../Hello';

it('renders correctly with defaults', () => {
    const hello = shallow(<Hello name="World" />);
    expect(hello.find(Text).render().text()).toEqual("Hello World!");
});

Which is testing this simple React Native component using only very basic React Native components:
https://github.com/Microsoft/TypeScript-React-Native-Starter/blob/master/src/components/Hello.tsx

  return (
    <View style={styles.root}>
        <Text style={styles.greeting}>
            Hello {name + getExclamationMarks(enthusiasmLevel)}
        </Text>
        <View style={styles.buttons}>
            <View style={styles.button}>
                <Button title="-" onPress={onDecrement || (() => {})} color='red' />
            </View>
            <View style={styles.button}>
                <Button title="+" onPress={onIncrement || (() => {})} color='blue' />
            </View>
        </View>
    </View>
  );

And I got the following warnings:

 PASS  src/components/__tests__/Hello.tsx
  ✓ renders correctly with defaults (33ms)

  console.error node_modules/fbjs/lib/warning.js:33
    Warning: <Text /> is using uppercase HTML. Always use lowercase HTML tags in React.

  console.error node_modules/fbjs/lib/warning.js:33
    Warning: Received `true` for a non-boolean attribute `accessible`.
    
    If you want to write it to the DOM, pass a string instead: accessible="true" or accessible={value.toString()}.
        in Text
        in Text

  console.error node_modules/fbjs/lib/warning.js:33
    Warning: React does not recognize the `allowFontScaling` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `allowfontscaling` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
        in Text
        in Text

  console.error node_modules/fbjs/lib/warning.js:33
    Warning: React does not recognize the `ellipsizeMode` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `ellipsizemode` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
        in Text
        in Text

@ljharb
Copy link
Member

ljharb commented Nov 25, 2017

React 16 is for React web - to properly use enzyme with react-native, we'd need an enzyme-adapter-react-native.

@mcdankyl
Copy link

mcdankyl commented Dec 8, 2017

@ljharb I'm interested in what would be required to make an enzyme-adapter-react-native. Is there anywhere where I can see documentation for implementing an adapter, or is just working off of the base react adapters the best?

Also, is there any effort to write the adapter already? I'd be curious of any information/insight you could give into seeing how a react-native adapter would work.

@ljharb
Copy link
Member

ljharb commented Dec 9, 2017

The best right now is to work off the base adapters.

I'm not aware of any current effort to write a react-native adapter.

@rmnegatives
Copy link

rmnegatives commented Dec 20, 2017

Honestly F** it I did this for now to stop all the red in my console. I will watch #1436

 describe('mounting', () => {
    const origConsole = console.error;
    beforeEach(() => {
      console.error = () => {};
    });
    afterEach(() => {
      console.error = origConsole;
    });
    it ...... 
       mount....
});

@ljharb
Copy link
Member

ljharb commented Dec 20, 2017

@rmnegatives that will silence propType warnings, which should be failing your tests.

@rmnegatives
Copy link

rmnegatives commented Dec 20, 2017

@ljharb yes it will, it is up to the developer to do due diligence check the warnings first, then fix the propType or any none 'DOM' type error. After things look good you can put in this temporary fix.

@zaguiini
Copy link

This should be fixed...

@coffenbacher
Copy link

Did anyone figure out how to do @rmnegatives hack with the new Jest 22 globalSetup hook so it doesn't have to be repeated in every file?

For example, I tried to put this in the global setup file and it runs, but doesn't suppress the issues.

module.exports = async () => {
    console.error = () => {}
}

@ljharb
Copy link
Member

ljharb commented Jul 6, 2018

You'd need a react native adapter to use enzyme with React Native.

Closing this in favor of #1436.

@ljharb ljharb closed this as completed Jul 6, 2018
@nikoremi97
Copy link

In Enzyme documentation, when creating setUp for Jest, add the following lines to the file:

const originalConsoleError = console.error;
console.error = (message) => {
  if (message.startsWith('Warning:')) {
    return;
  }

  originalConsoleError(message);
};

See full setUp file here: https://airbnb.io/enzyme/docs/guides/react-native.html#example-configuration-for-jest

@VannaDii
Copy link

VannaDii commented Oct 16, 2019

I know this issue is closed, but my searching landed me here, so I'll post this here for others who might also end up here.

I took this a bit further in my TypeScript + React-Native + Redux + Jest + Enzyme + Enzyme Adapter app in order to filter out the Warning: Unknown props ... messages and also the react-native-i18n module is not correctly linked messages. Below is my entire, working, enzyme.ts setup file.

Hopefully, this is helpful until a more concrete and official solution is available.

Also available as a Gist for sharing around.

import 'react-native';
import 'jest-enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Enzyme from 'enzyme';
import { global } from 'core-js';
import { JSDOM } from 'jsdom';

const jsdom = new JSDOM();
const { window } = jsdom;

function copyProps(src: any, target: any) {
  Object.defineProperties(target, {
    ...Object.getOwnPropertyDescriptors(src),
    ...Object.getOwnPropertyDescriptors(target),
  });
}

global.window = window;
global.document = window.document;
global.navigator = {
  userAgent: 'node.js',
};
copyProps(window, global);

function _getCallerFile() {
  const originalFunc = Error.prepareStackTrace;
  let callerFile: string = 'unknown';
  try {
    const err = new Error();
    let currentFile: string;
    let stack: NodeJS.CallSite[];
    let stackRecord: NodeJS.CallSite | undefined;

    Error.prepareStackTrace = function(err, stack) {
      return stack;
    };

    stack = <NodeJS.CallSite[]>(<unknown>err.stack);
    stackRecord = <NodeJS.CallSite>stack.shift();
    currentFile = stackRecord.getFileName() || '';

    while (stack.length) {
      stackRecord = <NodeJS.CallSite>stack.shift();
      callerFile = stackRecord.getFileName() || '';
      if (currentFile !== callerFile) break;
    }
  } catch (e) {
  } finally {
    Error.prepareStackTrace = originalFunc;
  }

  return callerFile;
}

function filteredConsole(
  original: (message?: any, ...optionalParams: any[]) => void,
  message?: any,
  ...optionalParams: any[]
) {
  const callerFile = _getCallerFile();
  const blockPattern = /.*(react-dom.development.js|module is not correctly linked)/i;
  if (!blockPattern.test(callerFile) && !blockPattern.test(message)) {
    original(message, ...optionalParams);
  }
}

const originalConsoleWarn = console.warn;
const originalConsoleError = console.error;
console.error = (message?: any, ...optionalParams: any[]) =>
  filteredConsole(originalConsoleError, message, ...optionalParams);
console.warn = (message?: any, ...optionalParams: any[]) =>
  filteredConsole(originalConsoleWarn, message, ...optionalParams);

Enzyme.configure({ adapter: new Adapter() });

@ivancmonaco
Copy link

Honestly F** it I did this for now to stop all the red in my console. I will watch #1436

 describe('mounting', () => {
    const origConsole = console.error;
    beforeEach(() => {
      console.error = () => {};
    });
    afterEach(() => {
      console.error = origConsole;
    });
    it ...... 
       mount....
});

A simple workaround to includes certain errors that we would like to log.
Still a temporary solution, but it works for me:

const origConsole = console.error;
const ALLOWED_ERROR_TAGS = ['failed prop type']
beforeEach(() => {
  console.error = e => {
      for(let tag of ALLOWED_ERROR_TAGS){
          if (e.toLowerCase().includes(tag.toLowerCase())) {
            console.warn(e);
            break
        }
      }
  };
});
afterEach(() => {
  console.error = origConsole;
});

@batoreh
Copy link

batoreh commented Apr 9, 2020

Hey guys, I found a tricky solution.

if you add to your test command both --verbose --silent it will remove all errors logs and keeps the checklist for each it.

worked well to me.

image

@ghasemikasra39
Copy link

Same issue. Any solution ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests