render function

RenderResult render(
  1. ReactElement ui, {
  2. Node? container,
  3. Node? baseElement,
  4. bool hydrate = false,
  5. dynamic wrapper,
  6. bool autoTearDown = true,
  7. void onDidTearDown()?,
})

Renders the ui element into the DOM, returning a RenderResult API that can be used to do things like RenderResult.rerender with different props, or to call a query function scoped within the container that was rendered into.

By default, the container will be removed from the DOM and RenderResult.unmount will be called along with an optional onDidTearDown in the tearDown of any test that calls this function unless autoTearDown is set to false.

See: testing-library.com/docs/react-testing-library/api#render

Example

import 'package:react/react.dart' as react;
import 'package:test/test.dart';
import 'package:react_testing_library/react_testing_library.dart' as rtl;
import 'package:react_testing_library/matchers.dart' show isInTheDocument;

main() {
  test('', () {
    final view = rtl.render(
      react.button({}, 'Click Me'),
    );

    // The `view` can now be used to query within the DOM!
    expect(view.getByRole('button', name: 'Click Me'), isInTheDocument);
  });
}

Options

container

By default, render will create a <div> and append that <div> to document.body and this is where your React component will be mounted/rendered. If you specify your own Node via the container option, it will not be appended to the document.body automatically.

For example: If you are unit testing a <tbody> element, it cannot be a child of a <div>. In this case, you can specify a <table> as the render container:

import 'dart:html';

import 'package:react/react.dart' as react;
import 'package:test/test.dart';
import 'package:react_testing_library/react_testing_library.dart' as rtl;

main() {
  test('', () {
    final tableElem = document.body.append(TableElement());
    final view = rtl.render(
      react.tbody({}, /*...*/),
      container: tableElem,
    );
  });
}

baseElement

If the container is specified, then baseElement defaults to that Node, otherwise this defaults to document.body. This is used as the base element for the queries as well as what is printed when you use RenderResult.debug.

wrapper

An OverReact UiFactory or a ReactComponentFactoryProxy which will be wrapped around the ui. This is especially useful when testing components that need a context provider of some kind.


Custom Queries Not Yet Supported

The JS react-testing-library implementation of render supports "custom queries". At this time, the Dart API does not support them. If you have a use case for custom queries -

we would love to hear more about it!

Implementation

RenderResult render(
  ReactElement ui, {
  Node? container,
  Node? baseElement,
  bool hydrate = false,
  // TODO: Implement if CPLAT-13502 is deemed necessary
  // Map<String, Query> queries,
  /*UiFactory || ReactComponentFactoryProxy*/ dynamic wrapper,
  bool autoTearDown = true,
  void Function()? onDidTearDown,
}) {
  // ignore: invalid_use_of_visible_for_testing_member
  componentZone = Zone.current;

  final renderOptions = RenderOptions()..hydrate = hydrate;
  if (container != null) renderOptions.container = container;
  if (baseElement != null) renderOptions.baseElement = baseElement;
  if (wrapper != null) {
    if (wrapper is ReactComponentFactoryProxy) {
      renderOptions.wrapper = wrapper.type;
    } else {
      // Its probably a UiFactory
      try {
        renderOptions.wrapper = wrapper().componentFactory.type;
      } catch (err) {
        throw ArgumentError.value(wrapper, 'wrapper', 'wrapper must be a ReactComponentFactoryProxy or UiFactory');
      }
    }
  }
  if (!autoTearDown && onDidTearDown != null) {
    throw ArgumentError('onDidTearDown cannot be set when autoTearDown is false.');
  }

  return spyOnConsoleLogs(
    () {
      final jsResult = _render(ui, renderOptions);
      if (autoTearDown) {
        addTearDown(() {
          jsResult.unmount();
          jsResult.container.remove();
          onDidTearDown?.call();
        });
      }
      return RenderResult._(jsResult, ui);
    },
    configuration: ConsoleConfig.error,
    onLog: (error) =>
        print('\x1B[33m⚠️  Warning: ${error.replaceFirst(RegExp(r'^Warning:?\s?', caseSensitive: false), '')}\x1B[0m'),
  );
}