Best JavaScript code snippet using playwright-internal
ReactShallowRendererMemo-test.js
Source:ReactShallowRendererMemo-test.js
...29 return <div />;30 }31 },32 );33 const shallowRenderer = createRenderer();34 shallowRenderer.render(<SomeComponent foo={1} />);35 // Calling cDU might lead to problems with host component references.36 // Since our components aren't really mounted, refs won't be available.37 expect(logs).toEqual(['componentWillMount']);38 logs.splice(0);39 const instance = shallowRenderer.getMountedInstance();40 instance.setState({});41 expect(logs).toEqual(['shouldComponentUpdate', 'componentWillUpdate']);42 logs.splice(0);43 shallowRenderer.render(<SomeComponent foo={2} />);44 // The previous shallow renderer did not trigger cDU for props changes.45 expect(logs).toEqual([46 'componentWillReceiveProps',47 'shouldComponentUpdate',48 'componentWillUpdate',49 ]);50 });51 it('should call all of the new lifecycle hooks', () => {52 const logs = [];53 const logger = message => () => logs.push(message) || true;54 const SomeComponent = React.memo(55 class SomeComponent extends React.Component {56 state = {};57 static getDerivedStateFromProps = logger('getDerivedStateFromProps');58 componentDidMount = logger('componentDidMount');59 shouldComponentUpdate = logger('shouldComponentUpdate');60 componentDidUpdate = logger('componentDidUpdate');61 componentWillUnmount = logger('componentWillUnmount');62 render() {63 return <div />;64 }65 },66 );67 const shallowRenderer = createRenderer();68 shallowRenderer.render(<SomeComponent foo={1} />);69 // Calling cDU might lead to problems with host component references.70 // Since our components aren't really mounted, refs won't be available.71 expect(logs).toEqual(['getDerivedStateFromProps']);72 logs.splice(0);73 const instance = shallowRenderer.getMountedInstance();74 instance.setState({});75 expect(logs).toEqual(['getDerivedStateFromProps', 'shouldComponentUpdate']);76 logs.splice(0);77 shallowRenderer.render(<SomeComponent foo={2} />);78 // The previous shallow renderer did not trigger cDU for props changes.79 expect(logs).toEqual(['getDerivedStateFromProps', 'shouldComponentUpdate']);80 });81 it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present', () => {82 const Component = React.memo(83 class Component extends React.Component {84 state = {};85 static getDerivedStateFromProps() {86 return null;87 }88 componentWillMount() {89 throw Error('unexpected');90 }91 componentWillReceiveProps() {92 throw Error('unexpected');93 }94 componentWillUpdate() {95 throw Error('unexpected');96 }97 render() {98 return null;99 }100 },101 );102 const shallowRenderer = createRenderer();103 shallowRenderer.render(<Component />);104 });105 it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new getSnapshotBeforeUpdate is present', () => {106 const Component = React.memo(107 class Component extends React.Component {108 getSnapshotBeforeUpdate() {109 return null;110 }111 componentWillMount() {112 throw Error('unexpected');113 }114 componentWillReceiveProps() {115 throw Error('unexpected');116 }117 componentWillUpdate() {118 throw Error('unexpected');119 }120 render() {121 return null;122 }123 },124 );125 const shallowRenderer = createRenderer();126 shallowRenderer.render(<Component value={1} />);127 shallowRenderer.render(<Component value={2} />);128 });129 it('should not call getSnapshotBeforeUpdate or componentDidUpdate when updating since refs wont exist', () => {130 const Component = React.memo(131 class Component extends React.Component {132 getSnapshotBeforeUpdate() {133 throw Error('unexpected');134 }135 componentDidUpdate() {136 throw Error('unexpected');137 }138 render() {139 return null;140 }141 },142 );143 const shallowRenderer = createRenderer();144 shallowRenderer.render(<Component value={1} />);145 shallowRenderer.render(<Component value={2} />);146 });147 it('should only render 1 level deep', () => {148 const Parent = React.memo(function Parent() {149 return (150 <div>151 <Child />152 </div>153 );154 });155 function Child() {156 throw Error('This component should not render');157 }158 const shallowRenderer = createRenderer();159 shallowRenderer.render(React.createElement(Parent));160 });161 it('should have shallow rendering', () => {162 const SomeComponent = React.memo(163 class SomeComponent extends React.Component {164 render() {165 return (166 <div>167 <span className="child1" />168 <span className="child2" />169 </div>170 );171 }172 },173 );174 const shallowRenderer = createRenderer();175 const result = shallowRenderer.render(<SomeComponent />);176 expect(result.type).toBe('div');177 expect(result.props.children).toEqual([178 <span className="child1" />,179 <span className="child2" />,180 ]);181 });182 it('should handle Profiler', () => {183 const SomeComponent = React.memo(184 class SomeComponent extends React.Component {185 render() {186 return (187 <React.Profiler id="test" onRender={jest.fn()}>188 <div>189 <span className="child1" />190 <span className="child2" />191 </div>192 </React.Profiler>193 );194 }195 },196 );197 const shallowRenderer = createRenderer();198 const result = shallowRenderer.render(<SomeComponent />);199 expect(result.type).toBe(React.Profiler);200 expect(result.props.children).toEqual(201 <div>202 <span className="child1" />203 <span className="child2" />204 </div>,205 );206 });207 it('should enable shouldComponentUpdate to prevent a re-render', () => {208 let renderCounter = 0;209 const SimpleComponent = React.memo(210 class SimpleComponent extends React.Component {211 state = {update: false};212 shouldComponentUpdate(nextProps, nextState) {213 return this.state.update !== nextState.update;214 }215 render() {216 renderCounter++;217 return <div>{`${renderCounter}`}</div>;218 }219 },220 );221 const shallowRenderer = createRenderer();222 shallowRenderer.render(<SimpleComponent />);223 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);224 const instance = shallowRenderer.getMountedInstance();225 instance.setState({update: false});226 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);227 instance.setState({update: true});228 expect(shallowRenderer.getRenderOutput()).toEqual(<div>2</div>);229 });230 it('should enable PureComponent to prevent a re-render', () => {231 let renderCounter = 0;232 const SimpleComponent = React.memo(233 class SimpleComponent extends React.PureComponent {234 state = {update: false};235 render() {236 renderCounter++;237 return <div>{`${renderCounter}`}</div>;238 }239 },240 );241 const shallowRenderer = createRenderer();242 shallowRenderer.render(<SimpleComponent />);243 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);244 const instance = shallowRenderer.getMountedInstance();245 instance.setState({update: false});246 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);247 instance.setState({update: true});248 expect(shallowRenderer.getRenderOutput()).toEqual(<div>2</div>);249 });250 it('should not run shouldComponentUpdate during forced update', () => {251 let scuCounter = 0;252 const SimpleComponent = React.memo(253 class SimpleComponent extends React.Component {254 state = {count: 1};255 shouldComponentUpdate() {256 scuCounter++;257 return false;258 }259 render() {260 return <div>{`${this.state.count}`}</div>;261 }262 },263 );264 const shallowRenderer = createRenderer();265 shallowRenderer.render(<SimpleComponent />);266 expect(scuCounter).toEqual(0);267 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);268 // Force update the initial state. sCU should not fire.269 const instance = shallowRenderer.getMountedInstance();270 instance.forceUpdate();271 expect(scuCounter).toEqual(0);272 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);273 // Setting state updates the instance, but doesn't re-render274 // because sCU returned false.275 instance.setState(state => ({count: state.count + 1}));276 expect(scuCounter).toEqual(1);277 expect(instance.state.count).toEqual(2);278 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);279 // A force update updates the render output, but doesn't call sCU.280 instance.forceUpdate();281 expect(scuCounter).toEqual(1);282 expect(instance.state.count).toEqual(2);283 expect(shallowRenderer.getRenderOutput()).toEqual(<div>2</div>);284 });285 it('should rerender when calling forceUpdate', () => {286 let renderCounter = 0;287 const SimpleComponent = React.memo(288 class SimpleComponent extends React.Component {289 render() {290 renderCounter += 1;291 return <div />;292 }293 },294 );295 const shallowRenderer = createRenderer();296 shallowRenderer.render(<SimpleComponent />);297 expect(renderCounter).toEqual(1);298 const instance = shallowRenderer.getMountedInstance();299 instance.forceUpdate();300 expect(renderCounter).toEqual(2);301 });302 it('should shallow render a function component', () => {303 function SomeComponent(props, context) {304 return (305 <div>306 <div>{props.foo}</div>307 <div>{context.bar}</div>308 <span className="child1" />309 <span className="child2" />310 </div>311 );312 }313 const SomeMemoComponent = React.memo(SomeComponent);314 SomeComponent.contextTypes = {315 bar: PropTypes.string,316 };317 const shallowRenderer = createRenderer();318 const result = shallowRenderer.render(<SomeMemoComponent foo={'FOO'} />, {319 bar: 'BAR',320 });321 expect(result.type).toBe('div');322 expect(result.props.children).toEqual([323 <div>FOO</div>,324 <div>BAR</div>,325 <span className="child1" />,326 <span className="child2" />,327 ]);328 });329 it('should shallow render a component returning strings directly from render', () => {330 const Text = React.memo(({value}) => value);331 const shallowRenderer = createRenderer();332 const result = shallowRenderer.render(<Text value="foo" />);333 expect(result).toEqual('foo');334 });335 it('should shallow render a component returning numbers directly from render', () => {336 const Text = React.memo(({value}) => value);337 const shallowRenderer = createRenderer();338 const result = shallowRenderer.render(<Text value={10} />);339 expect(result).toEqual(10);340 });341 it('should shallow render a fragment', () => {342 class SomeComponent extends React.Component {343 render() {344 return <div />;345 }346 }347 class Fragment extends React.Component {348 render() {349 return [<div key="a" />, <span key="b" />, <SomeComponent />];350 }351 }352 const shallowRenderer = createRenderer();353 const result = shallowRenderer.render(<Fragment />);354 expect(result).toEqual([355 <div key="a" />,356 <span key="b" />,357 <SomeComponent />,358 ]);359 });360 it('should shallow render a React.fragment', () => {361 class SomeComponent extends React.Component {362 render() {363 return <div />;364 }365 }366 class Fragment extends React.Component {367 render() {368 return (369 <>370 <div />371 <span />372 <SomeComponent />373 </>374 );375 }376 }377 const shallowRenderer = createRenderer();378 const result = shallowRenderer.render(<Fragment />);379 expect(result).toEqual(380 <>381 <div />382 <span />383 <SomeComponent />384 </>,385 );386 });387 it('should throw for invalid elements', () => {388 class SomeComponent extends React.Component {389 render() {390 return <div />;391 }392 }393 const shallowRenderer = createRenderer();394 expect(() => shallowRenderer.render(SomeComponent)).toThrowError(395 'ReactShallowRenderer render(): Invalid component element. Instead of ' +396 'passing a component class, make sure to instantiate it by passing it ' +397 'to React.createElement.',398 );399 expect(() => shallowRenderer.render(<div />)).toThrowError(400 'ReactShallowRenderer render(): Shallow rendering works only with ' +401 'custom components, not primitives (div). Instead of calling ' +402 '`.render(el)` and inspecting the rendered output, look at `el.props` ' +403 'directly instead.',404 );405 });406 it('should have shallow unmounting', () => {407 const componentWillUnmount = jest.fn();408 class SomeComponent extends React.Component {409 componentWillUnmount = componentWillUnmount;410 render() {411 return <div />;412 }413 }414 const shallowRenderer = createRenderer();415 shallowRenderer.render(<SomeComponent />);416 shallowRenderer.unmount();417 expect(componentWillUnmount).toBeCalled();418 });419 it('can shallow render to null', () => {420 class SomeComponent extends React.Component {421 render() {422 return null;423 }424 }425 const shallowRenderer = createRenderer();426 const result = shallowRenderer.render(<SomeComponent />);427 expect(result).toBe(null);428 });429 it('can shallow render with a ref', () => {430 class SomeComponent extends React.Component {431 render() {432 return <div ref="hello" />;433 }434 }435 const shallowRenderer = createRenderer();436 // Shouldn't crash.437 shallowRenderer.render(<SomeComponent />);438 });439 it('lets you update shallowly rendered components', () => {440 class SomeComponent extends React.Component {441 state = {clicked: false};442 onClick = () => {443 this.setState({clicked: true});444 };445 render() {446 const className = this.state.clicked ? 'was-clicked' : '';447 if (this.props.aNew === 'prop') {448 return (449 <a href="#" onClick={this.onClick} className={className}>450 Test link451 </a>452 );453 } else {454 return (455 <div>456 <span className="child1" />457 <span className="child2" />458 </div>459 );460 }461 }462 }463 const shallowRenderer = createRenderer();464 const result = shallowRenderer.render(<SomeComponent />);465 expect(result.type).toBe('div');466 expect(result.props.children).toEqual([467 <span className="child1" />,468 <span className="child2" />,469 ]);470 const updatedResult = shallowRenderer.render(<SomeComponent aNew="prop" />);471 expect(updatedResult.type).toBe('a');472 const mockEvent = {};473 updatedResult.props.onClick(mockEvent);474 const updatedResultCausedByClick = shallowRenderer.getRenderOutput();475 expect(updatedResultCausedByClick.type).toBe('a');476 expect(updatedResultCausedByClick.props.className).toBe('was-clicked');477 });478 it('can access the mounted component instance', () => {479 const SimpleComponent = React.memo(480 class SimpleComponent extends React.Component {481 someMethod = () => {482 return this.props.n;483 };484 render() {485 return <div>{this.props.n}</div>;486 }487 },488 );489 const shallowRenderer = createRenderer();490 shallowRenderer.render(<SimpleComponent n={5} />);491 expect(shallowRenderer.getMountedInstance().someMethod()).toEqual(5);492 });493 it('can shallowly render components with contextTypes', () => {494 const SimpleComponent = React.memo(495 class SimpleComponent extends React.Component {496 static contextTypes = {497 name: PropTypes.string,498 };499 render() {500 return <div />;501 }502 },503 );504 const shallowRenderer = createRenderer();505 const result = shallowRenderer.render(<SimpleComponent />);506 expect(result).toEqual(<div />);507 });508 it('passes expected params to legacy component lifecycle methods', () => {509 const componentDidUpdateParams = [];510 const componentWillReceivePropsParams = [];511 const componentWillUpdateParams = [];512 const setStateParams = [];513 const shouldComponentUpdateParams = [];514 const initialProp = {prop: 'init prop'};515 const initialState = {state: 'init state'};516 const initialContext = {context: 'init context'};517 const updatedState = {state: 'updated state'};518 const updatedProp = {prop: 'updated prop'};519 const updatedContext = {context: 'updated context'};520 const SimpleComponent = React.memo(521 class SimpleComponent extends React.Component {522 constructor(props, context) {523 super(props, context);524 this.state = initialState;525 }526 static contextTypes = {527 context: PropTypes.string,528 };529 componentDidUpdate(...args) {530 componentDidUpdateParams.push(...args);531 }532 UNSAFE_componentWillReceiveProps(...args) {533 componentWillReceivePropsParams.push(...args);534 this.setState((...innerArgs) => {535 setStateParams.push(...innerArgs);536 return updatedState;537 });538 }539 UNSAFE_componentWillUpdate(...args) {540 componentWillUpdateParams.push(...args);541 }542 shouldComponentUpdate(...args) {543 shouldComponentUpdateParams.push(...args);544 return true;545 }546 render() {547 return null;548 }549 },550 );551 const shallowRenderer = createRenderer();552 shallowRenderer.render(553 React.createElement(SimpleComponent, initialProp),554 initialContext,555 );556 expect(componentDidUpdateParams).toEqual([]);557 expect(componentWillReceivePropsParams).toEqual([]);558 expect(componentWillUpdateParams).toEqual([]);559 expect(setStateParams).toEqual([]);560 expect(shouldComponentUpdateParams).toEqual([]);561 // Lifecycle hooks should be invoked with the correct prev/next params on update.562 shallowRenderer.render(563 React.createElement(SimpleComponent, updatedProp),564 updatedContext,565 );566 expect(componentWillReceivePropsParams).toEqual([567 updatedProp,568 updatedContext,569 ]);570 expect(setStateParams).toEqual([initialState, initialProp]);571 expect(shouldComponentUpdateParams).toEqual([572 updatedProp,573 updatedState,574 updatedContext,575 ]);576 expect(componentWillUpdateParams).toEqual([577 updatedProp,578 updatedState,579 updatedContext,580 ]);581 expect(componentDidUpdateParams).toEqual([]);582 });583 it('passes expected params to new component lifecycle methods', () => {584 const componentDidUpdateParams = [];585 const getDerivedStateFromPropsParams = [];586 const shouldComponentUpdateParams = [];587 const initialProp = {prop: 'init prop'};588 const initialState = {state: 'init state'};589 const initialContext = {context: 'init context'};590 const updatedProp = {prop: 'updated prop'};591 const updatedContext = {context: 'updated context'};592 const SimpleComponent = React.memo(593 class SimpleComponent extends React.Component {594 constructor(props, context) {595 super(props, context);596 this.state = initialState;597 }598 static contextTypes = {599 context: PropTypes.string,600 };601 componentDidUpdate(...args) {602 componentDidUpdateParams.push(...args);603 }604 static getDerivedStateFromProps(...args) {605 getDerivedStateFromPropsParams.push(args);606 return null;607 }608 shouldComponentUpdate(...args) {609 shouldComponentUpdateParams.push(...args);610 return true;611 }612 render() {613 return null;614 }615 },616 );617 const shallowRenderer = createRenderer();618 // The only lifecycle hook that should be invoked on initial render619 // Is the static getDerivedStateFromProps() methods620 shallowRenderer.render(621 React.createElement(SimpleComponent, initialProp),622 initialContext,623 );624 expect(getDerivedStateFromPropsParams).toEqual([625 [initialProp, initialState],626 ]);627 expect(componentDidUpdateParams).toEqual([]);628 expect(shouldComponentUpdateParams).toEqual([]);629 // Lifecycle hooks should be invoked with the correct prev/next params on update.630 shallowRenderer.render(631 React.createElement(SimpleComponent, updatedProp),632 updatedContext,633 );634 expect(getDerivedStateFromPropsParams).toEqual([635 [initialProp, initialState],636 [updatedProp, initialState],637 ]);638 expect(shouldComponentUpdateParams).toEqual([639 updatedProp,640 initialState,641 updatedContext,642 ]);643 expect(componentDidUpdateParams).toEqual([]);644 });645 it('can shallowly render components with ref as function', () => {646 const SimpleComponent = React.memo(647 class SimpleComponent extends React.Component {648 state = {clicked: false};649 handleUserClick = () => {650 this.setState({clicked: true});651 };652 render() {653 return (654 <div655 ref={() => {}}656 onClick={this.handleUserClick}657 className={this.state.clicked ? 'clicked' : ''}658 />659 );660 }661 },662 );663 const shallowRenderer = createRenderer();664 shallowRenderer.render(<SimpleComponent />);665 let result = shallowRenderer.getRenderOutput();666 expect(result.type).toEqual('div');667 expect(result.props.className).toEqual('');668 result.props.onClick();669 result = shallowRenderer.getRenderOutput();670 expect(result.type).toEqual('div');671 expect(result.props.className).toEqual('clicked');672 });673 it('can initialize state via static getDerivedStateFromProps', () => {674 const SimpleComponent = React.memo(675 class SimpleComponent extends React.Component {676 state = {677 count: 1,678 };679 static getDerivedStateFromProps(props, prevState) {680 return {681 count: prevState.count + props.incrementBy,682 other: 'foobar',683 };684 }685 render() {686 return (687 <div>{`count:${this.state.count}, other:${this.state.other}`}</div>688 );689 }690 },691 );692 const shallowRenderer = createRenderer();693 const result = shallowRenderer.render(<SimpleComponent incrementBy={2} />);694 expect(result).toEqual(<div>count:3, other:foobar</div>);695 });696 it('can setState in componentWillMount when shallow rendering', () => {697 const SimpleComponent = React.memo(698 class SimpleComponent extends React.Component {699 UNSAFE_componentWillMount() {700 this.setState({groovy: 'doovy'});701 }702 render() {703 return <div>{this.state.groovy}</div>;704 }705 },706 );707 const shallowRenderer = createRenderer();708 const result = shallowRenderer.render(<SimpleComponent />);709 expect(result).toEqual(<div>doovy</div>);710 });711 it('can setState in componentWillMount repeatedly when shallow rendering', () => {712 const SimpleComponent = React.memo(713 class SimpleComponent extends React.Component {714 state = {715 separator: '-',716 };717 UNSAFE_componentWillMount() {718 this.setState({groovy: 'doovy'});719 this.setState({doovy: 'groovy'});720 }721 render() {722 const {groovy, doovy, separator} = this.state;723 return <div>{`${groovy}${separator}${doovy}`}</div>;724 }725 },726 );727 const shallowRenderer = createRenderer();728 const result = shallowRenderer.render(<SimpleComponent />);729 expect(result).toEqual(<div>doovy-groovy</div>);730 });731 it('can setState in componentWillMount with an updater function repeatedly when shallow rendering', () => {732 const SimpleComponent = React.memo(733 class SimpleComponent extends React.Component {734 state = {735 separator: '-',736 };737 UNSAFE_componentWillMount() {738 this.setState(state => ({groovy: 'doovy'}));739 this.setState(state => ({doovy: state.groovy}));740 }741 render() {742 const {groovy, doovy, separator} = this.state;743 return <div>{`${groovy}${separator}${doovy}`}</div>;744 }745 },746 );747 const shallowRenderer = createRenderer();748 const result = shallowRenderer.render(<SimpleComponent />);749 expect(result).toEqual(<div>doovy-doovy</div>);750 });751 it('can setState in componentWillReceiveProps when shallow rendering', () => {752 const SimpleComponent = React.memo(753 class SimpleComponent extends React.Component {754 state = {count: 0};755 UNSAFE_componentWillReceiveProps(nextProps) {756 if (nextProps.updateState) {757 this.setState({count: 1});758 }759 }760 render() {761 return <div>{this.state.count}</div>;762 }763 },764 );765 const shallowRenderer = createRenderer();766 let result = shallowRenderer.render(767 <SimpleComponent updateState={false} />,768 );769 expect(result.props.children).toEqual(0);770 result = shallowRenderer.render(<SimpleComponent updateState={true} />);771 expect(result.props.children).toEqual(1);772 });773 it('can update state with static getDerivedStateFromProps when shallow rendering', () => {774 const SimpleComponent = React.memo(775 class SimpleComponent extends React.Component {776 state = {count: 1};777 static getDerivedStateFromProps(nextProps, prevState) {778 if (nextProps.updateState) {779 return {count: nextProps.incrementBy + prevState.count};780 }781 return null;782 }783 render() {784 return <div>{this.state.count}</div>;785 }786 },787 );788 const shallowRenderer = createRenderer();789 let result = shallowRenderer.render(790 <SimpleComponent updateState={false} incrementBy={0} />,791 );792 expect(result.props.children).toEqual(1);793 result = shallowRenderer.render(794 <SimpleComponent updateState={true} incrementBy={2} />,795 );796 expect(result.props.children).toEqual(3);797 result = shallowRenderer.render(798 <SimpleComponent updateState={false} incrementBy={2} />,799 );800 expect(result.props.children).toEqual(3);801 });802 it('should not override state with stale values if prevState is spread within getDerivedStateFromProps', () => {803 const SimpleComponent = React.memo(804 class SimpleComponent extends React.Component {805 state = {value: 0};806 static getDerivedStateFromProps(nextProps, prevState) {807 return {...prevState};808 }809 updateState = () => {810 this.setState(state => ({value: state.value + 1}));811 };812 render() {813 return <div>{`value:${this.state.value}`}</div>;814 }815 },816 );817 const shallowRenderer = createRenderer();818 let result = shallowRenderer.render(<SimpleComponent />);819 expect(result).toEqual(<div>value:0</div>);820 const instance = shallowRenderer.getMountedInstance();821 instance.updateState();822 result = shallowRenderer.getRenderOutput();823 expect(result).toEqual(<div>value:1</div>);824 });825 it('should pass previous state to shouldComponentUpdate even with getDerivedStateFromProps', () => {826 const SimpleComponent = React.memo(827 class SimpleComponent extends React.Component {828 constructor(props) {829 super(props);830 this.state = {831 value: props.value,832 };833 }834 static getDerivedStateFromProps(nextProps, prevState) {835 if (nextProps.value === prevState.value) {836 return null;837 }838 return {value: nextProps.value};839 }840 shouldComponentUpdate(nextProps, nextState) {841 return nextState.value !== this.state.value;842 }843 render() {844 return <div>{`value:${this.state.value}`}</div>;845 }846 },847 );848 const shallowRenderer = createRenderer();849 const initialResult = shallowRenderer.render(850 <SimpleComponent value="initial" />,851 );852 expect(initialResult).toEqual(<div>value:initial</div>);853 const updatedResult = shallowRenderer.render(854 <SimpleComponent value="updated" />,855 );856 expect(updatedResult).toEqual(<div>value:updated</div>);857 });858 it('can setState with an updater function', () => {859 let instance;860 const SimpleComponent = React.memo(861 class SimpleComponent extends React.Component {862 state = {863 counter: 0,864 };865 render() {866 instance = this;867 return (868 <button ref="button" onClick={this.onClick}>869 {this.state.counter}870 </button>871 );872 }873 },874 );875 const shallowRenderer = createRenderer();876 let result = shallowRenderer.render(<SimpleComponent defaultCount={1} />);877 expect(result.props.children).toEqual(0);878 instance.setState((state, props) => {879 return {counter: props.defaultCount + 1};880 });881 result = shallowRenderer.getRenderOutput();882 expect(result.props.children).toEqual(2);883 });884 it('can access component instance from setState updater function', done => {885 let instance;886 const SimpleComponent = React.memo(887 class SimpleComponent extends React.Component {888 state = {};889 render() {890 instance = this;891 return null;892 }893 },894 );895 const shallowRenderer = createRenderer();896 shallowRenderer.render(<SimpleComponent />);897 instance.setState(function updater(state, props) {898 expect(this).toBe(instance);899 done();900 });901 });902 it('can setState with a callback', () => {903 let instance;904 const SimpleComponent = React.memo(905 class SimpleComponent extends React.Component {906 state = {907 counter: 0,908 };909 render() {910 instance = this;911 return <p>{this.state.counter}</p>;912 }913 },914 );915 const shallowRenderer = createRenderer();916 const result = shallowRenderer.render(<SimpleComponent />);917 expect(result.props.children).toBe(0);918 const callback = jest.fn(function() {919 expect(this).toBe(instance);920 });921 instance.setState({counter: 1}, callback);922 const updated = shallowRenderer.getRenderOutput();923 expect(updated.props.children).toBe(1);924 expect(callback).toHaveBeenCalled();925 });926 it('can replaceState with a callback', () => {927 let instance;928 const SimpleComponent = React.memo(929 class SimpleComponent extends React.Component {930 state = {931 counter: 0,932 };933 render() {934 instance = this;935 return <p>{this.state.counter}</p>;936 }937 },938 );939 const shallowRenderer = createRenderer();940 const result = shallowRenderer.render(<SimpleComponent />);941 expect(result.props.children).toBe(0);942 const callback = jest.fn(function() {943 expect(this).toBe(instance);944 });945 // No longer a public API, but we can test that it works internally by946 // reaching into the updater.947 shallowRenderer._updater.enqueueReplaceState(948 instance,949 {counter: 1},950 callback,951 );952 const updated = shallowRenderer.getRenderOutput();953 expect(updated.props.children).toBe(1);954 expect(callback).toHaveBeenCalled();955 });956 it('can forceUpdate with a callback', () => {957 let instance;958 const SimpleComponent = React.memo(959 class SimpleComponent extends React.Component {960 state = {961 counter: 0,962 };963 render() {964 instance = this;965 return <p>{this.state.counter}</p>;966 }967 },968 );969 const shallowRenderer = createRenderer();970 const result = shallowRenderer.render(<SimpleComponent />);971 expect(result.props.children).toBe(0);972 const callback = jest.fn(function() {973 expect(this).toBe(instance);974 });975 instance.forceUpdate(callback);976 const updated = shallowRenderer.getRenderOutput();977 expect(updated.props.children).toBe(0);978 expect(callback).toHaveBeenCalled();979 });980 it('can pass context when shallowly rendering', () => {981 const SimpleComponent = React.memo(982 class SimpleComponent extends React.Component {983 static contextTypes = {984 name: PropTypes.string,985 };986 render() {987 return <div>{this.context.name}</div>;988 }989 },990 );991 const shallowRenderer = createRenderer();992 const result = shallowRenderer.render(<SimpleComponent />, {993 name: 'foo',994 });995 expect(result).toEqual(<div>foo</div>);996 });997 it('should track context across updates', () => {998 const SimpleComponent = React.memo(999 class SimpleComponent extends React.Component {1000 static contextTypes = {1001 foo: PropTypes.string,1002 };1003 state = {1004 bar: 'bar',1005 };1006 render() {1007 return <div>{`${this.context.foo}:${this.state.bar}`}</div>;1008 }1009 },1010 );1011 const shallowRenderer = createRenderer();1012 let result = shallowRenderer.render(<SimpleComponent />, {1013 foo: 'foo',1014 });1015 expect(result).toEqual(<div>foo:bar</div>);1016 const instance = shallowRenderer.getMountedInstance();1017 instance.setState({bar: 'baz'});1018 result = shallowRenderer.getRenderOutput();1019 expect(result).toEqual(<div>foo:baz</div>);1020 });1021 it('should filter context by contextTypes', () => {1022 const SimpleComponent = React.memo(1023 class SimpleComponent extends React.Component {1024 static contextTypes = {1025 foo: PropTypes.string,1026 };1027 render() {1028 return <div>{`${this.context.foo}:${this.context.bar}`}</div>;1029 }1030 },1031 );1032 const shallowRenderer = createRenderer();1033 const result = shallowRenderer.render(<SimpleComponent />, {1034 foo: 'foo',1035 bar: 'bar',1036 });1037 expect(result).toEqual(<div>foo:undefined</div>);1038 });1039 it('can fail context when shallowly rendering', () => {1040 const SimpleComponent = React.memo(1041 class SimpleComponent extends React.Component {1042 static contextTypes = {1043 name: PropTypes.string.isRequired,1044 };1045 render() {1046 return <div>{this.context.name}</div>;1047 }1048 },1049 );1050 const shallowRenderer = createRenderer();1051 expect(() => shallowRenderer.render(<SimpleComponent />)).toErrorDev(1052 'Warning: Failed context type: The context `name` is marked as ' +1053 'required in `SimpleComponent`, but its value is `undefined`.\n' +1054 ' in SimpleComponent (at **)',1055 );1056 });1057 it('should warn about propTypes (but only once)', () => {1058 const SimpleComponent = React.memo(1059 class SimpleComponent extends React.Component {1060 static propTypes = {1061 name: PropTypes.string.isRequired,1062 };1063 render() {1064 return React.createElement('div', null, this.props.name);1065 }1066 },1067 );1068 const shallowRenderer = createRenderer();1069 expect(() =>1070 shallowRenderer.render(React.createElement(SimpleComponent, {name: 123})),1071 ).toErrorDev(1072 'Warning: Failed prop type: Invalid prop `name` of type `number` ' +1073 'supplied to `SimpleComponent`, expected `string`.\n' +1074 ' in SimpleComponent',1075 );1076 });1077 it('should enable rendering of cloned element', () => {1078 const SimpleComponent = React.memo(1079 class SimpleComponent extends React.Component {1080 constructor(props) {1081 super(props);1082 this.state = {1083 bar: 'bar',1084 };1085 }1086 render() {1087 return <div>{`${this.props.foo}:${this.state.bar}`}</div>;1088 }1089 },1090 );1091 const shallowRenderer = createRenderer();1092 const el = <SimpleComponent foo="foo" />;1093 let result = shallowRenderer.render(el);1094 expect(result).toEqual(<div>foo:bar</div>);1095 const cloned = React.cloneElement(el, {foo: 'baz'});1096 result = shallowRenderer.render(cloned);1097 expect(result).toEqual(<div>baz:bar</div>);1098 });1099 it('this.state should be updated on setState callback inside componentWillMount', () => {1100 let stateSuccessfullyUpdated = false;1101 const Component = React.memo(1102 class Component extends React.Component {1103 constructor(props, context) {1104 super(props, context);1105 this.state = {1106 hasUpdatedState: false,1107 };1108 }1109 UNSAFE_componentWillMount() {1110 this.setState(1111 {hasUpdatedState: true},1112 () => (stateSuccessfullyUpdated = this.state.hasUpdatedState),1113 );1114 }1115 render() {1116 return <div>{this.props.children}</div>;1117 }1118 },1119 );1120 const shallowRenderer = createRenderer();1121 shallowRenderer.render(<Component />);1122 expect(stateSuccessfullyUpdated).toBe(true);1123 });1124 it('should handle multiple callbacks', () => {1125 const mockFn = jest.fn();1126 const shallowRenderer = createRenderer();1127 const Component = React.memo(1128 class Component extends React.Component {1129 constructor(props, context) {1130 super(props, context);1131 this.state = {1132 foo: 'foo',1133 };1134 }1135 UNSAFE_componentWillMount() {1136 this.setState({foo: 'bar'}, () => mockFn());1137 this.setState({foo: 'foobar'}, () => mockFn());1138 }1139 render() {1140 return <div>{this.state.foo}</div>;1141 }1142 },1143 );1144 shallowRenderer.render(<Component />);1145 expect(mockFn).toHaveBeenCalledTimes(2);1146 // Ensure the callback queue is cleared after the callbacks are invoked1147 const mountedInstance = shallowRenderer.getMountedInstance();1148 mountedInstance.setState({foo: 'bar'}, () => mockFn());1149 expect(mockFn).toHaveBeenCalledTimes(3);1150 });1151 it('should call the setState callback even if shouldComponentUpdate = false', done => {1152 const mockFn = jest.fn().mockReturnValue(false);1153 const Component = React.memo(1154 class Component extends React.Component {1155 constructor(props, context) {1156 super(props, context);1157 this.state = {1158 hasUpdatedState: false,1159 };1160 }1161 shouldComponentUpdate() {1162 return mockFn();1163 }1164 render() {1165 return <div>{this.state.hasUpdatedState}</div>;1166 }1167 },1168 );1169 const shallowRenderer = createRenderer();1170 shallowRenderer.render(<Component />);1171 const mountedInstance = shallowRenderer.getMountedInstance();1172 mountedInstance.setState({hasUpdatedState: true}, () => {1173 expect(mockFn).toBeCalled();1174 expect(mountedInstance.state.hasUpdatedState).toBe(true);1175 done();1176 });1177 });1178 it('throws usefully when rendering badly-typed elements', () => {1179 const shallowRenderer = createRenderer();1180 const renderAndVerifyWarningAndError = (Component, typeString) => {1181 expect(() => {1182 expect(() => shallowRenderer.render(<Component />)).toErrorDev(1183 'React.createElement: type is invalid -- expected a string ' +1184 '(for built-in components) or a class/function (for composite components) ' +1185 `but got: ${typeString}.`,1186 );1187 }).toThrowError(1188 'ReactShallowRenderer render(): Shallow rendering works only with custom ' +1189 `components, but the provided element type was \`${typeString}\`.`,1190 );1191 };1192 renderAndVerifyWarningAndError(undefined, 'undefined');1193 renderAndVerifyWarningAndError(null, 'null');1194 renderAndVerifyWarningAndError([], 'array');1195 renderAndVerifyWarningAndError({}, 'object');1196 });1197 it('should have initial state of null if not defined', () => {1198 const SomeComponent = React.memo(1199 class SomeComponent extends React.Component {1200 render() {1201 return <span />;1202 }1203 },1204 );1205 const shallowRenderer = createRenderer();1206 shallowRenderer.render(<SomeComponent />);1207 expect(shallowRenderer.getMountedInstance().state).toBeNull();1208 });1209 it('should invoke both deprecated and new lifecycles if both are present', () => {1210 const log = [];1211 const Component = React.memo(1212 class Component extends React.Component {1213 componentWillMount() {1214 log.push('componentWillMount');1215 }1216 componentWillReceiveProps() {1217 log.push('componentWillReceiveProps');1218 }1219 componentWillUpdate() {1220 log.push('componentWillUpdate');1221 }1222 UNSAFE_componentWillMount() {1223 log.push('UNSAFE_componentWillMount');1224 }1225 UNSAFE_componentWillReceiveProps() {1226 log.push('UNSAFE_componentWillReceiveProps');1227 }1228 UNSAFE_componentWillUpdate() {1229 log.push('UNSAFE_componentWillUpdate');1230 }1231 render() {1232 return null;1233 }1234 },1235 );1236 const shallowRenderer = createRenderer();1237 shallowRenderer.render(<Component foo="bar" />);1238 expect(log).toEqual(['componentWillMount', 'UNSAFE_componentWillMount']);1239 log.length = 0;1240 shallowRenderer.render(<Component foo="baz" />);1241 expect(log).toEqual([1242 'componentWillReceiveProps',1243 'UNSAFE_componentWillReceiveProps',1244 'componentWillUpdate',1245 'UNSAFE_componentWillUpdate',1246 ]);1247 });1248 it('should stop the update when setState returns null or undefined', () => {1249 const log = [];1250 let instance;1251 const Component = React.memo(1252 class Component extends React.Component {1253 constructor(props) {1254 super(props);1255 this.state = {1256 count: 0,1257 };1258 }1259 render() {1260 log.push('render');1261 instance = this;1262 return null;1263 }1264 },1265 );1266 const shallowRenderer = createRenderer();1267 shallowRenderer.render(<Component />);1268 log.length = 0;1269 instance.setState(() => null);1270 instance.setState(() => undefined);1271 instance.setState(null);1272 instance.setState(undefined);1273 expect(log).toEqual([]);1274 instance.setState(state => ({count: state.count + 1}));1275 expect(log).toEqual(['render']);1276 });1277 it('should not get this in a function component', () => {1278 const logs = [];1279 const Foo = React.memo(function Foo() {1280 logs.push(this);1281 return <div>foo</div>;1282 });1283 const shallowRenderer = createRenderer();1284 shallowRenderer.render(<Foo foo="bar" />);1285 expect(logs).toEqual([undefined]);1286 });...
ReactShallowRenderer-test.js
Source:ReactShallowRenderer-test.js
...30 render() {31 return <div />;32 }33 }34 const shallowRenderer = createRenderer();35 shallowRenderer.render(<SomeComponent foo={1} />);36 // Calling cDU might lead to problems with host component references.37 // Since our components aren't really mounted, refs won't be available.38 expect(logs).toEqual(['componentWillMount']);39 logs.splice(0);40 const instance = shallowRenderer.getMountedInstance();41 instance.setState({});42 expect(logs).toEqual(['shouldComponentUpdate', 'componentWillUpdate']);43 logs.splice(0);44 shallowRenderer.render(<SomeComponent foo={2} />);45 // The previous shallow renderer did not trigger cDU for props changes.46 expect(logs).toEqual([47 'componentWillReceiveProps',48 'shouldComponentUpdate',49 'componentWillUpdate',50 ]);51 });52 it('should only render 1 level deep', () => {53 function Parent() {54 return (55 <div>56 <Child />57 </div>58 );59 }60 function Child() {61 throw Error('This component should not render');62 }63 const shallowRenderer = createRenderer();64 shallowRenderer.render(React.createElement(Parent));65 });66 it('should have shallow rendering', () => {67 class SomeComponent extends React.Component {68 render() {69 return (70 <div>71 <span className="child1" />72 <span className="child2" />73 </div>74 );75 }76 }77 const shallowRenderer = createRenderer();78 const result = shallowRenderer.render(<SomeComponent />);79 expect(result.type).toBe('div');80 expect(result.props.children).toEqual([81 <span className="child1" />,82 <span className="child2" />,83 ]);84 });85 it('should enable shouldComponentUpdate to prevent a re-render', () => {86 let renderCounter = 0;87 class SimpleComponent extends React.Component {88 state = {update: false};89 shouldComponentUpdate(nextProps, nextState) {90 return this.state.update !== nextState.update;91 }92 render() {93 renderCounter++;94 return <div>{`${renderCounter}`}</div>;95 }96 }97 const shallowRenderer = createRenderer();98 shallowRenderer.render(<SimpleComponent />);99 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);100 const instance = shallowRenderer.getMountedInstance();101 instance.setState({update: false});102 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);103 instance.setState({update: true});104 expect(shallowRenderer.getRenderOutput()).toEqual(<div>2</div>);105 });106 it('should enable PureComponent to prevent a re-render', () => {107 let renderCounter = 0;108 class SimpleComponent extends React.PureComponent {109 state = {update: false};110 render() {111 renderCounter++;112 return <div>{`${renderCounter}`}</div>;113 }114 }115 const shallowRenderer = createRenderer();116 shallowRenderer.render(<SimpleComponent />);117 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);118 const instance = shallowRenderer.getMountedInstance();119 instance.setState({update: false});120 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);121 instance.setState({update: true});122 expect(shallowRenderer.getRenderOutput()).toEqual(<div>2</div>);123 });124 it('should not run shouldComponentUpdate during forced update', () => {125 let scuCounter = 0;126 class SimpleComponent extends React.Component {127 state = {count: 1};128 shouldComponentUpdate() {129 scuCounter++;130 return false;131 }132 render() {133 return <div>{`${this.state.count}`}</div>;134 }135 }136 const shallowRenderer = createRenderer();137 shallowRenderer.render(<SimpleComponent />);138 expect(scuCounter).toEqual(0);139 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);140 // Force update the initial state. sCU should not fire.141 const instance = shallowRenderer.getMountedInstance();142 instance.forceUpdate();143 expect(scuCounter).toEqual(0);144 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);145 // Setting state updates the instance, but doesn't re-render146 // because sCU returned false.147 instance.setState(state => ({count: state.count + 1}));148 expect(scuCounter).toEqual(1);149 expect(instance.state.count).toEqual(2);150 expect(shallowRenderer.getRenderOutput()).toEqual(<div>1</div>);151 // A force update updates the render output, but doesn't call sCU.152 instance.forceUpdate();153 expect(scuCounter).toEqual(1);154 expect(instance.state.count).toEqual(2);155 expect(shallowRenderer.getRenderOutput()).toEqual(<div>2</div>);156 });157 it('should rerender when calling forceUpdate', () => {158 let renderCounter = 0;159 class SimpleComponent extends React.Component {160 render() {161 renderCounter += 1;162 return <div />;163 }164 }165 const shallowRenderer = createRenderer();166 shallowRenderer.render(<SimpleComponent />);167 expect(renderCounter).toEqual(1);168 const instance = shallowRenderer.getMountedInstance();169 instance.forceUpdate();170 expect(renderCounter).toEqual(2);171 });172 it('should shallow render a functional component', () => {173 function SomeComponent(props, context) {174 return (175 <div>176 <div>{props.foo}</div>177 <div>{context.bar}</div>178 <span className="child1" />179 <span className="child2" />180 </div>181 );182 }183 const shallowRenderer = createRenderer();184 const result = shallowRenderer.render(<SomeComponent foo={'FOO'} />, {185 bar: 'BAR',186 });187 expect(result.type).toBe('div');188 expect(result.props.children).toEqual([189 <div>FOO</div>,190 <div>BAR</div>,191 <span className="child1" />,192 <span className="child2" />,193 ]);194 });195 it('should shallow render a component returning strings directly from render', () => {196 const Text = ({value}) => value;197 const shallowRenderer = createRenderer();198 const result = shallowRenderer.render(<Text value="foo" />);199 expect(result).toEqual('foo');200 });201 it('should shallow render a component returning numbers directly from render', () => {202 const Text = ({value}) => value;203 const shallowRenderer = createRenderer();204 const result = shallowRenderer.render(<Text value={10} />);205 expect(result).toEqual(10);206 });207 it('should shallow render a fragment', () => {208 class SomeComponent extends React.Component {209 render() {210 return <div />;211 }212 }213 class Fragment extends React.Component {214 render() {215 return [<div key="a" />, <span key="b" />, <SomeComponent />];216 }217 }218 const shallowRenderer = createRenderer();219 const result = shallowRenderer.render(<Fragment />);220 expect(result).toEqual([221 <div key="a" />,222 <span key="b" />,223 <SomeComponent />,224 ]);225 });226 it('should throw for invalid elements', () => {227 class SomeComponent extends React.Component {228 render() {229 return <div />;230 }231 }232 const shallowRenderer = createRenderer();233 expect(() => shallowRenderer.render(SomeComponent)).toThrowError(234 'ReactShallowRenderer render(): Invalid component element. Instead of ' +235 'passing a component class, make sure to instantiate it by passing it ' +236 'to React.createElement.',237 );238 expect(() => shallowRenderer.render(<div />)).toThrowError(239 'ReactShallowRenderer render(): Shallow rendering works only with ' +240 'custom components, not primitives (div). Instead of calling ' +241 '`.render(el)` and inspecting the rendered output, look at `el.props` ' +242 'directly instead.',243 );244 });245 it('should have shallow unmounting', () => {246 const componentWillUnmount = jest.fn();247 class SomeComponent extends React.Component {248 componentWillUnmount = componentWillUnmount;249 render() {250 return <div />;251 }252 }253 const shallowRenderer = createRenderer();254 shallowRenderer.render(<SomeComponent />);255 shallowRenderer.unmount();256 expect(componentWillUnmount).toBeCalled();257 });258 it('can shallow render to null', () => {259 class SomeComponent extends React.Component {260 render() {261 return null;262 }263 }264 const shallowRenderer = createRenderer();265 const result = shallowRenderer.render(<SomeComponent />);266 expect(result).toBe(null);267 });268 it('can shallow render with a ref', () => {269 class SomeComponent extends React.Component {270 render() {271 return <div ref="hello" />;272 }273 }274 const shallowRenderer = createRenderer();275 // Shouldn't crash.276 shallowRenderer.render(<SomeComponent />);277 });278 it('lets you update shallowly rendered components', () => {279 class SomeComponent extends React.Component {280 state = {clicked: false};281 onClick = () => {282 this.setState({clicked: true});283 };284 render() {285 const className = this.state.clicked ? 'was-clicked' : '';286 if (this.props.aNew === 'prop') {287 return (288 <a href="#" onClick={this.onClick} className={className}>289 Test link290 </a>291 );292 } else {293 return (294 <div>295 <span className="child1" />296 <span className="child2" />297 </div>298 );299 }300 }301 }302 const shallowRenderer = createRenderer();303 const result = shallowRenderer.render(<SomeComponent />);304 expect(result.type).toBe('div');305 expect(result.props.children).toEqual([306 <span className="child1" />,307 <span className="child2" />,308 ]);309 const updatedResult = shallowRenderer.render(<SomeComponent aNew="prop" />);310 expect(updatedResult.type).toBe('a');311 const mockEvent = {};312 updatedResult.props.onClick(mockEvent);313 const updatedResultCausedByClick = shallowRenderer.getRenderOutput();314 expect(updatedResultCausedByClick.type).toBe('a');315 expect(updatedResultCausedByClick.props.className).toBe('was-clicked');316 });317 it('can access the mounted component instance', () => {318 class SimpleComponent extends React.Component {319 someMethod = () => {320 return this.props.n;321 };322 render() {323 return <div>{this.props.n}</div>;324 }325 }326 const shallowRenderer = createRenderer();327 shallowRenderer.render(<SimpleComponent n={5} />);328 expect(shallowRenderer.getMountedInstance().someMethod()).toEqual(5);329 });330 it('can shallowly render components with contextTypes', () => {331 class SimpleComponent extends React.Component {332 static contextTypes = {333 name: PropTypes.string,334 };335 render() {336 return <div />;337 }338 }339 const shallowRenderer = createRenderer();340 const result = shallowRenderer.render(<SimpleComponent />);341 expect(result).toEqual(<div />);342 });343 it('passes expected params to component lifecycle methods', () => {344 const componentDidUpdateParams = [];345 const componentWillReceivePropsParams = [];346 const componentWillUpdateParams = [];347 const setStateParams = [];348 const shouldComponentUpdateParams = [];349 const initialProp = {prop: 'init prop'};350 const initialState = {state: 'init state'};351 const initialContext = {context: 'init context'};352 const updatedState = {state: 'updated state'};353 const updatedProp = {prop: 'updated prop'};354 const updatedContext = {context: 'updated context'};355 class SimpleComponent extends React.Component {356 constructor(props, context) {357 super(props, context);358 this.state = initialState;359 }360 componentDidUpdate(...args) {361 componentDidUpdateParams.push(...args);362 }363 componentWillReceiveProps(...args) {364 componentWillReceivePropsParams.push(...args);365 this.setState((...innerArgs) => {366 setStateParams.push(...innerArgs);367 return updatedState;368 });369 }370 componentWillUpdate(...args) {371 componentWillUpdateParams.push(...args);372 }373 shouldComponentUpdate(...args) {374 shouldComponentUpdateParams.push(...args);375 return true;376 }377 render() {378 return null;379 }380 }381 const shallowRenderer = createRenderer();382 // No lifecycle hooks should be invoked on initial render383 shallowRenderer.render(384 React.createElement(SimpleComponent, initialProp),385 initialContext,386 );387 expect(componentDidUpdateParams).toEqual([]);388 expect(componentWillReceivePropsParams).toEqual([]);389 expect(componentWillUpdateParams).toEqual([]);390 expect(setStateParams).toEqual([]);391 expect(shouldComponentUpdateParams).toEqual([]);392 // Lifecycle hooks should be invoked with the correct prev/next params on update.393 shallowRenderer.render(394 React.createElement(SimpleComponent, updatedProp),395 updatedContext,396 );397 expect(componentWillReceivePropsParams).toEqual([398 updatedProp,399 updatedContext,400 ]);401 expect(setStateParams).toEqual([initialState, initialProp]);402 expect(shouldComponentUpdateParams).toEqual([403 updatedProp,404 updatedState,405 updatedContext,406 ]);407 expect(componentWillUpdateParams).toEqual([408 updatedProp,409 updatedState,410 updatedContext,411 ]);412 expect(componentDidUpdateParams).toEqual([]);413 });414 it('can shallowly render components with ref as function', () => {415 class SimpleComponent extends React.Component {416 state = {clicked: false};417 handleUserClick = () => {418 this.setState({clicked: true});419 };420 render() {421 return (422 <div423 ref={() => {}}424 onClick={this.handleUserClick}425 className={this.state.clicked ? 'clicked' : ''}426 />427 );428 }429 }430 const shallowRenderer = createRenderer();431 shallowRenderer.render(<SimpleComponent />);432 let result = shallowRenderer.getRenderOutput();433 expect(result.type).toEqual('div');434 expect(result.props.className).toEqual('');435 result.props.onClick();436 result = shallowRenderer.getRenderOutput();437 expect(result.type).toEqual('div');438 expect(result.props.className).toEqual('clicked');439 });440 it('can setState in componentWillMount when shallow rendering', () => {441 class SimpleComponent extends React.Component {442 componentWillMount() {443 this.setState({groovy: 'doovy'});444 }445 render() {446 return <div>{this.state.groovy}</div>;447 }448 }449 const shallowRenderer = createRenderer();450 const result = shallowRenderer.render(<SimpleComponent />);451 expect(result).toEqual(<div>doovy</div>);452 });453 it('can setState in componentWillMount repeatedly when shallow rendering', () => {454 class SimpleComponent extends React.Component {455 state = {456 separator: '-',457 };458 componentWillMount() {459 this.setState({groovy: 'doovy'});460 this.setState({doovy: 'groovy'});461 }462 render() {463 const {groovy, doovy, separator} = this.state;464 return <div>{`${groovy}${separator}${doovy}`}</div>;465 }466 }467 const shallowRenderer = createRenderer();468 const result = shallowRenderer.render(<SimpleComponent />);469 expect(result).toEqual(<div>doovy-groovy</div>);470 });471 it('can setState in componentWillMount with an updater function repeatedly when shallow rendering', () => {472 class SimpleComponent extends React.Component {473 state = {474 separator: '-',475 };476 componentWillMount() {477 this.setState(state => ({groovy: 'doovy'}));478 this.setState(state => ({doovy: state.groovy}));479 }480 render() {481 const {groovy, doovy, separator} = this.state;482 return <div>{`${groovy}${separator}${doovy}`}</div>;483 }484 }485 const shallowRenderer = createRenderer();486 const result = shallowRenderer.render(<SimpleComponent />);487 expect(result).toEqual(<div>doovy-doovy</div>);488 });489 it('can setState in componentWillReceiveProps when shallow rendering', () => {490 class SimpleComponent extends React.Component {491 state = {count: 0};492 componentWillReceiveProps(nextProps) {493 if (nextProps.updateState) {494 this.setState({count: 1});495 }496 }497 render() {498 return <div>{this.state.count}</div>;499 }500 }501 const shallowRenderer = createRenderer();502 let result = shallowRenderer.render(503 <SimpleComponent updateState={false} />,504 );505 expect(result.props.children).toEqual(0);506 result = shallowRenderer.render(<SimpleComponent updateState={true} />);507 expect(result.props.children).toEqual(1);508 });509 it('can setState with an updater function', () => {510 let instance;511 class SimpleComponent extends React.Component {512 state = {513 counter: 0,514 };515 render() {516 instance = this;517 return (518 <button ref="button" onClick={this.onClick}>519 {this.state.counter}520 </button>521 );522 }523 }524 const shallowRenderer = createRenderer();525 let result = shallowRenderer.render(<SimpleComponent defaultCount={1} />);526 expect(result.props.children).toEqual(0);527 instance.setState((state, props) => {528 return {counter: props.defaultCount + 1};529 });530 result = shallowRenderer.getRenderOutput();531 expect(result.props.children).toEqual(2);532 });533 it('can setState with a callback', () => {534 let instance;535 class SimpleComponent extends React.Component {536 state = {537 counter: 0,538 };539 render() {540 instance = this;541 return <p>{this.state.counter}</p>;542 }543 }544 const shallowRenderer = createRenderer();545 const result = shallowRenderer.render(<SimpleComponent />);546 expect(result.props.children).toBe(0);547 const callback = jest.fn(function() {548 expect(this).toBe(instance);549 });550 instance.setState({counter: 1}, callback);551 const updated = shallowRenderer.getRenderOutput();552 expect(updated.props.children).toBe(1);553 expect(callback).toHaveBeenCalled();554 });555 it('can replaceState with a callback', () => {556 let instance;557 class SimpleComponent extends React.Component {558 state = {559 counter: 0,560 };561 render() {562 instance = this;563 return <p>{this.state.counter}</p>;564 }565 }566 const shallowRenderer = createRenderer();567 const result = shallowRenderer.render(<SimpleComponent />);568 expect(result.props.children).toBe(0);569 const callback = jest.fn(function() {570 expect(this).toBe(instance);571 });572 // No longer a public API, but we can test that it works internally by573 // reaching into the updater.574 shallowRenderer._updater.enqueueReplaceState(575 instance,576 {counter: 1},577 callback,578 );579 const updated = shallowRenderer.getRenderOutput();580 expect(updated.props.children).toBe(1);581 expect(callback).toHaveBeenCalled();582 });583 it('can forceUpdate with a callback', () => {584 let instance;585 class SimpleComponent extends React.Component {586 state = {587 counter: 0,588 };589 render() {590 instance = this;591 return <p>{this.state.counter}</p>;592 }593 }594 const shallowRenderer = createRenderer();595 const result = shallowRenderer.render(<SimpleComponent />);596 expect(result.props.children).toBe(0);597 const callback = jest.fn(function() {598 expect(this).toBe(instance);599 });600 instance.forceUpdate(callback);601 const updated = shallowRenderer.getRenderOutput();602 expect(updated.props.children).toBe(0);603 expect(callback).toHaveBeenCalled();604 });605 it('can pass context when shallowly rendering', () => {606 class SimpleComponent extends React.Component {607 static contextTypes = {608 name: PropTypes.string,609 };610 render() {611 return <div>{this.context.name}</div>;612 }613 }614 const shallowRenderer = createRenderer();615 const result = shallowRenderer.render(<SimpleComponent />, {616 name: 'foo',617 });618 expect(result).toEqual(<div>foo</div>);619 });620 it('should track context across updates', () => {621 class SimpleComponent extends React.Component {622 static contextTypes = {623 foo: PropTypes.string,624 };625 state = {626 bar: 'bar',627 };628 render() {629 return <div>{`${this.context.foo}:${this.state.bar}`}</div>;630 }631 }632 const shallowRenderer = createRenderer();633 let result = shallowRenderer.render(<SimpleComponent />, {634 foo: 'foo',635 });636 expect(result).toEqual(<div>foo:bar</div>);637 const instance = shallowRenderer.getMountedInstance();638 instance.setState({bar: 'baz'});639 result = shallowRenderer.getRenderOutput();640 expect(result).toEqual(<div>foo:baz</div>);641 });642 it('can fail context when shallowly rendering', () => {643 spyOnDev(console, 'error');644 class SimpleComponent extends React.Component {645 static contextTypes = {646 name: PropTypes.string.isRequired,647 };648 render() {649 return <div>{this.context.name}</div>;650 }651 }652 const shallowRenderer = createRenderer();653 shallowRenderer.render(<SimpleComponent />);654 if (__DEV__) {655 expect(console.error.calls.count()).toBe(1);656 expect(657 console.error.calls.argsFor(0)[0].replace(/\(at .+?:\d+\)/g, '(at **)'),658 ).toBe(659 'Warning: Failed context type: The context `name` is marked as ' +660 'required in `SimpleComponent`, but its value is `undefined`.\n' +661 ' in SimpleComponent (at **)',662 );663 }664 });665 it('should warn about propTypes (but only once)', () => {666 spyOnDev(console, 'error');667 class SimpleComponent extends React.Component {668 render() {669 return React.createElement('div', null, this.props.name);670 }671 }672 SimpleComponent.propTypes = {673 name: PropTypes.string.isRequired,674 };675 const shallowRenderer = createRenderer();676 shallowRenderer.render(React.createElement(SimpleComponent, {name: 123}));677 if (__DEV__) {678 expect(console.error.calls.count()).toBe(1);679 expect(680 console.error.calls.argsFor(0)[0].replace(/\(at .+?:\d+\)/g, '(at **)'),681 ).toBe(682 'Warning: Failed prop type: Invalid prop `name` of type `number` ' +683 'supplied to `SimpleComponent`, expected `string`.\n' +684 ' in SimpleComponent',685 );686 }687 });688 it('should enable rendering of cloned element', () => {689 class SimpleComponent extends React.Component {690 constructor(props) {691 super(props);692 this.state = {693 bar: 'bar',694 };695 }696 render() {697 return <div>{`${this.props.foo}:${this.state.bar}`}</div>;698 }699 }700 const shallowRenderer = createRenderer();701 const el = <SimpleComponent foo="foo" />;702 let result = shallowRenderer.render(el);703 expect(result).toEqual(<div>foo:bar</div>);704 const cloned = React.cloneElement(el, {foo: 'baz'});705 result = shallowRenderer.render(cloned);706 expect(result).toEqual(<div>baz:bar</div>);707 });708 it('this.state should be updated on setState callback inside componentWillMount', () => {709 let stateSuccessfullyUpdated = false;710 class Component extends React.Component {711 constructor(props, context) {712 super(props, context);713 this.state = {714 hasUpdatedState: false,715 };716 }717 componentWillMount() {718 this.setState(719 {hasUpdatedState: true},720 () => (stateSuccessfullyUpdated = this.state.hasUpdatedState),721 );722 }723 render() {724 return <div>{this.props.children}</div>;725 }726 }727 const shallowRenderer = createRenderer();728 shallowRenderer.render(<Component />);729 expect(stateSuccessfullyUpdated).toBe(true);730 });731 it('should handle multiple callbacks', () => {732 const mockFn = jest.fn();733 const shallowRenderer = createRenderer();734 class Component extends React.Component {735 constructor(props, context) {736 super(props, context);737 this.state = {738 foo: 'foo',739 };740 }741 componentWillMount() {742 this.setState({foo: 'bar'}, () => mockFn());743 this.setState({foo: 'foobar'}, () => mockFn());744 }745 render() {746 return <div>{this.state.foo}</div>;747 }748 }749 shallowRenderer.render(<Component />);750 expect(mockFn.mock.calls.length).toBe(2);751 // Ensure the callback queue is cleared after the callbacks are invoked752 const mountedInstance = shallowRenderer.getMountedInstance();753 mountedInstance.setState({foo: 'bar'}, () => mockFn());754 expect(mockFn.mock.calls.length).toBe(3);755 });756 it('should call the setState callback even if shouldComponentUpdate = false', done => {757 const mockFn = jest.fn().mockReturnValue(false);758 class Component extends React.Component {759 constructor(props, context) {760 super(props, context);761 this.state = {762 hasUpdatedState: false,763 };764 }765 shouldComponentUpdate() {766 return mockFn();767 }768 render() {769 return <div>{this.state.hasUpdatedState}</div>;770 }771 }772 const shallowRenderer = createRenderer();773 shallowRenderer.render(<Component />);774 const mountedInstance = shallowRenderer.getMountedInstance();775 mountedInstance.setState({hasUpdatedState: true}, () => {776 expect(mockFn).toBeCalled();777 expect(mountedInstance.state.hasUpdatedState).toBe(true);778 done();779 });780 });781 it('throws usefully when rendering badly-typed elements', () => {782 spyOnDev(console, 'error');783 const shallowRenderer = createRenderer();784 var Undef = undefined;785 expect(() => shallowRenderer.render(<Undef />)).toThrowError(786 'ReactShallowRenderer render(): Shallow rendering works only with custom ' +787 'components, but the provided element type was `undefined`.',788 );789 var Null = null;790 expect(() => shallowRenderer.render(<Null />)).toThrowError(791 'ReactShallowRenderer render(): Shallow rendering works only with custom ' +792 'components, but the provided element type was `null`.',793 );794 var Arr = [];795 expect(() => shallowRenderer.render(<Arr />)).toThrowError(796 'ReactShallowRenderer render(): Shallow rendering works only with custom ' +797 'components, but the provided element type was `array`.',...
ssr-bundle-render.spec.js
Source:ssr-bundle-render.spec.js
...34 createAssertions(false)35})36function createAssertions (runInNewContext) {37 it('renderToString', done => {38 createRenderer('app.js', { runInNewContext }, renderer => {39 const context = { url: '/test' }40 renderer.renderToString(context, (err, res) => {41 expect(err).toBeNull()42 expect(res).toBe('<div data-server-rendered="true">/test</div>')43 expect(context.msg).toBe('hello')44 done()45 })46 })47 })48 it('renderToStream', done => {49 createRenderer('app.js', { runInNewContext }, renderer => {50 const context = { url: '/test' }51 const stream = renderer.renderToStream(context)52 let res = ''53 stream.on('data', chunk => {54 res += chunk.toString()55 })56 stream.on('end', () => {57 expect(res).toBe('<div data-server-rendered="true">/test</div>')58 expect(context.msg).toBe('hello')59 done()60 })61 })62 })63 it('renderToString catch error', done => {64 createRenderer('error.js', { runInNewContext }, renderer => {65 renderer.renderToString(err => {66 expect(err.message).toBe('foo')67 done()68 })69 })70 })71 it('renderToString catch Promise rejection', done => {72 createRenderer('promise-rejection.js', { runInNewContext }, renderer => {73 renderer.renderToString(err => {74 expect(err.message).toBe('foo')75 done()76 })77 })78 })79 it('renderToStream catch error', done => {80 createRenderer('error.js', { runInNewContext }, renderer => {81 const stream = renderer.renderToStream()82 stream.on('error', err => {83 expect(err.message).toBe('foo')84 done()85 })86 })87 })88 it('renderToStream catch Promise rejection', done => {89 createRenderer('promise-rejection.js', { runInNewContext }, renderer => {90 const stream = renderer.renderToStream()91 stream.on('error', err => {92 expect(err.message).toBe('foo')93 done()94 })95 })96 })97 it('render with cache (get/set)', done => {98 const cache = {}99 const get = jasmine.createSpy('get')100 const set = jasmine.createSpy('set')101 const options = {102 runInNewContext,103 cache: {104 // async105 get: (key, cb) => {106 setTimeout(() => {107 get(key)108 cb(cache[key])109 }, 0)110 },111 set: (key, val) => {112 set(key, val)113 cache[key] = val114 }115 }116 }117 createRenderer('cache.js', options, renderer => {118 const expected = '<div data-server-rendered="true">/test</div>'119 const key = 'app::1'120 renderer.renderToString((err, res) => {121 expect(err).toBeNull()122 expect(res).toBe(expected)123 expect(get).toHaveBeenCalledWith(key)124 const setArgs = set.calls.argsFor(0)125 expect(setArgs[0]).toBe(key)126 expect(setArgs[1].html).toBe(expected)127 expect(cache[key].html).toBe(expected)128 renderer.renderToString((err, res) => {129 expect(err).toBeNull()130 expect(res).toBe(expected)131 expect(get.calls.count()).toBe(2)132 expect(set.calls.count()).toBe(1)133 done()134 })135 })136 })137 })138 it('render with cache (get/set/has)', done => {139 const cache = {}140 const has = jasmine.createSpy('has')141 const get = jasmine.createSpy('get')142 const set = jasmine.createSpy('set')143 const options = {144 runInNewContext,145 cache: {146 // async147 has: (key, cb) => {148 has(key)149 cb(!!cache[key])150 },151 // sync152 get: key => {153 get(key)154 return cache[key]155 },156 set: (key, val) => {157 set(key, val)158 cache[key] = val159 }160 }161 }162 createRenderer('cache.js', options, renderer => {163 const expected = '<div data-server-rendered="true">/test</div>'164 const key = 'app::1'165 renderer.renderToString((err, res) => {166 expect(err).toBeNull()167 expect(res).toBe(expected)168 expect(has).toHaveBeenCalledWith(key)169 expect(get).not.toHaveBeenCalled()170 const setArgs = set.calls.argsFor(0)171 expect(setArgs[0]).toBe(key)172 expect(setArgs[1].html).toBe(expected)173 expect(cache[key].html).toBe(expected)174 renderer.renderToString((err, res) => {175 expect(err).toBeNull()176 expect(res).toBe(expected)177 expect(has.calls.count()).toBe(2)178 expect(get.calls.count()).toBe(1)179 expect(set.calls.count()).toBe(1)180 done()181 })182 })183 })184 })185 it('render with cache (nested)', done => {186 const cache = LRU({ maxAge: Infinity })187 spyOn(cache, 'get').and.callThrough()188 spyOn(cache, 'set').and.callThrough()189 const options = {190 cache,191 runInNewContext192 }193 createRenderer('nested-cache.js', options, renderer => {194 const expected = '<div data-server-rendered="true">/test</div>'195 const key = 'app::1'196 const context1 = { registered: [] }197 const context2 = { registered: [] }198 renderer.renderToString(context1, (err, res) => {199 expect(err).toBeNull()200 expect(res).toBe(expected)201 expect(cache.set.calls.count()).toBe(3) // 3 nested components cached202 const cached = cache.get(key)203 expect(cached.html).toBe(expected)204 expect(cache.get.calls.count()).toBe(1)205 // assert component usage registration for nested children206 expect(context1.registered).toEqual(['app', 'child', 'grandchild'])207 renderer.renderToString(context2, (err, res) => {208 expect(err).toBeNull()209 expect(res).toBe(expected)210 expect(cache.set.calls.count()).toBe(3) // no new cache sets211 expect(cache.get.calls.count()).toBe(2) // 1 get for root212 expect(context2.registered).toEqual(['app', 'child', 'grandchild'])213 done()214 })215 })216 })217 })218 it('renderToString (bundle format with code split)', done => {219 createRenderer('split.js', { runInNewContext, asBundle: true }, renderer => {220 const context = { url: '/test' }221 renderer.renderToString(context, (err, res) => {222 expect(err).toBeNull()223 expect(res).toBe('<div data-server-rendered="true">/test<div>async test.woff2 test.png</div></div>')224 done()225 })226 })227 })228 it('renderToStream (bundle format with code split)', done => {229 createRenderer('split.js', { runInNewContext, asBundle: true }, renderer => {230 const context = { url: '/test' }231 const stream = renderer.renderToStream(context)232 let res = ''233 stream.on('data', chunk => {234 res += chunk.toString()235 })236 stream.on('end', () => {237 expect(res).toBe('<div data-server-rendered="true">/test<div>async test.woff2 test.png</div></div>')238 done()239 })240 })241 })242 it('renderToString catch error (bundle format with source map)', done => {243 createRenderer('error.js', { runInNewContext, asBundle: true }, renderer => {244 renderer.renderToString(err => {245 expect(err.stack).toContain('test/ssr/fixtures/error.js:1:6')246 expect(err.message).toBe('foo')247 done()248 })249 })250 })251 it('renderToString catch error (bundle format with source map)', done => {252 createRenderer('error.js', { runInNewContext, asBundle: true }, renderer => {253 const stream = renderer.renderToStream()254 stream.on('error', err => {255 expect(err.stack).toContain('test/ssr/fixtures/error.js:1:6')256 expect(err.message).toBe('foo')257 done()258 })259 })260 })261 it('renderToString return Promise', done => {262 createRenderer('app.js', { runInNewContext }, renderer => {263 const context = { url: '/test' }264 renderer.renderToString(context).then(res => {265 expect(res).toBe('<div data-server-rendered="true">/test</div>')266 expect(context.msg).toBe('hello')267 done()268 })269 })270 })271 it('renderToString return Promise (error)', done => {272 createRenderer('error.js', { runInNewContext }, renderer => {273 renderer.renderToString().catch(err => {274 expect(err.message).toBe('foo')275 done()276 })277 })278 })279 it('renderToString return Promise (Promise rejection)', done => {280 createRenderer('promise-rejection.js', { runInNewContext }, renderer => {281 renderer.renderToString().catch(err => {282 expect(err.message).toBe('foo')283 done()284 })285 })286 })...
Button.test.js
Source:Button.test.js
...11import TestUtils from 'react-addons-test-utils';12const Button = require('../../components/Button/Button.react');13describe('Button', () => {14 it('has a default state', () => {15 const shallowRenderer = TestUtils.createRenderer();16 shallowRenderer.render(<Button value='A button' />);17 const component = shallowRenderer.getRenderOutput();18 expect(component.type).toBe('a');19 expect(component.props.className).toBe('button unselectable');20 expect(component.props.children.type).toBe('span');21 expect(component.props.children.props.children).toBe('A button');22 });23 it('can be primary', () => {24 const shallowRenderer = TestUtils.createRenderer();25 shallowRenderer.render(<Button primary={true} value='A button' />);26 const component = shallowRenderer.getRenderOutput();27 expect(component.type).toBe('a');28 expect(component.props.className).toBe('button unselectable primary');29 });30 it('can be colored', () => {31 const shallowRenderer = TestUtils.createRenderer();32 shallowRenderer.render(<Button color='red' value='A button' />);33 const component = shallowRenderer.getRenderOutput();34 expect(component.type).toBe('a');35 expect(component.props.className).toBe('button unselectable red');36 });37 it('can be colored and primary', () => {38 const shallowRenderer = TestUtils.createRenderer();39 shallowRenderer.render(<Button color='red' primary={true} value='A button' />);40 const component = shallowRenderer.getRenderOutput();41 expect(component.type).toBe('a');42 expect(component.props.className).toBe('button unselectable primary red');43 });44 it('can be disabled', () => {45 const shallowRenderer = TestUtils.createRenderer();46 shallowRenderer.render(<Button color='red' disabled={true} value='A button' />);47 const component = shallowRenderer.getRenderOutput();48 expect(component.type).toBe('a');49 expect(component.props.className).toBe('button unselectable disabled');50 });51 it('special-cases white disabled buttons', () => {52 const shallowRenderer = TestUtils.createRenderer();53 shallowRenderer.render(<Button color='white' disabled={true} value='A button' />);54 const component = shallowRenderer.getRenderOutput();55 expect(component.type).toBe('a');56 expect(component.props.className).toBe('button unselectable disabled white');57 });58 it('can indidate progress', () => {59 const shallowRenderer = TestUtils.createRenderer();60 shallowRenderer.render(<Button progress={true} value='A button' />);61 const component = shallowRenderer.getRenderOutput();62 expect(component.type).toBe('a');63 expect(component.props.className).toBe('button unselectable progress');64 });65 it('can override width', () => {66 const shallowRenderer = TestUtils.createRenderer();67 shallowRenderer.render(<Button width='300px' value='A button' />);68 const component = shallowRenderer.getRenderOutput();69 expect(component.type).toBe('a');70 expect(component.props.style.width).toBe('300px');71 });...
Using AI Code Generation
1const { webkit } = require('playwright');2(async () => {3 const browser = await webkit.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const renderer = await page._delegate.createRenderer();7 const path = require('path');8 const fs = require('fs');9 const outputFile = path.join(__dirname, 'output.pdf');10 const pdf = await renderer.pdf({ format: 'A4' });11 fs.writeFileSync(outputFile, pdf);12 await browser.close();13})();
Using AI Code Generation
1const { chromium } = require('playwright');2const { createRenderer } = require('playwright/lib/server/supplements/recorder/recorderApp');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 const renderer = await createRenderer(page);7 await page.click('text="Sign in"');8 await page.click('input[name="identifier"]');9 await page.fill('input[name="identifier"]', 'playwright');10 await page.click('text="Next"');11 await page.click('input[name="password"]');12 await page.fill('input[name="password"]', 'playwright');13 await page.click('text="Next"');14 await page.click('text="Gmail"');15 await page.click('text="Compose"');16 await page.click('input[name="to"]');17 await page.fill('input[name="to"]', '
Using AI Code Generation
1const { createRenderer } = require('playwright/lib/server/supplements/recorder/recorderApp');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 const renderer = await createRenderer(page);7 await page.click('text="I agree"');8 await page.click('input[aria-label="Search"]');9 await page.fill('input[aria-label="Search"]', 'Playwright');10 await page.press('input[aria-label="Search"]', 'Enter');11 await page.click('text="Playwright"');12 await page.click('text="Docs"');13 await page.click('text="API"');14 await page.click('text="Page"');15 await page.click('tex
Using AI Code Generation
1import { createRenderer } from 'playwright/lib/server/frames';2import { chromium } from 'playwright';3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 const renderer = createRenderer(page);8 const html = await renderer.renderToString();9 console.log(html);10 await browser.close();11})();12### `createRenderer(page: Page): Renderer`13#### `renderer.renderToString(): Promise<string>`14#### `renderer.renderToElementHandle(): Promise<ElementHandle>`15#### `renderer.renderToBuffer(): Promise<Buffer>`
Using AI Code Generation
1const { chromium } = require('playwright');2const { createRenderer } = require('playwright-core/lib/server/supplements/recorder/recorderApp');3const renderer = createRenderer();4(async () => {5 const browser = await chromium.launch();6 const page = await browser.newPage();7 const html = await renderer.render(page);8 console.log(html);9 await browser.close();10})();
Using AI Code Generation
1const playwright = require('playwright');2const { createRenderer } = require('playwright/lib/server/chromium/crPage');3const { chromium } = require('playwright');4(async () => {5 const browser = await chromium.launch();6 const context = await browser.newContext();7 const page = await context.newPage();8 const renderer = await createRenderer(page);9 await renderer.render({10 viewport: { width: 1280, height: 720 }11 });12 await browser.close();13})();14const playwright = require('playwright');15const { createRenderer } = require('playwright/lib/server/chromium/crPage');16const { chromium } = require('playwright');17(async () => {18 const browser = await chromium.launch();19 const context = await browser.newContext();20 const page = await context.newPage();21 const renderer = await createRenderer(page);22 await renderer.render({23 viewport: { width: 1280, height: 720 }24 });25 await browser.close();26})();27const playwright = require('playwright');28const { createRenderer } = require('playwright/lib/server/chromium/crPage');29const { chromium } = require('playwright');30(async () => {31 const browser = await chromium.launch();32 const context = await browser.newContext();33 const page = await context.newPage();34 const renderer = await createRenderer(page);35 await renderer.render({36 viewport: { width: 1280, height: 720 }37 });38 await browser.close();39})();40const playwright = require('playwright');41const { createRenderer } = require('playwright/lib/server/chromium/crPage');42const { chromium } = require('playwright');43(async () => {44 const browser = await chromium.launch();45 const context = await browser.newContext();46 const page = await context.newPage();47 const renderer = await createRenderer(page);48 await renderer.render({49 viewport: { width: 1280, height:
Using AI Code Generation
1const { createRenderer } = require('playwright/lib/server/chromium/crPage');2const { helper } = require('playwright/lib/helper');3(async () => {4 const renderer = await createRenderer();5 const page = await renderer.newPage();6 await page.setContent('<div>Test</div>');7 await page.screenshot({ path: 'test.png' });8 await renderer.close();9})();10const { CRPage } = require('playwright/lib/server/chromium/crPage');11const { CRBrowserContext } = require('playwright/lib/server/chromium/crBrowser');12const { BrowserContext } = require('playwright/lib/server/browserContext');13const { Page } = require('playwright/lib/server/page');14const { helper } = require('playwright/lib/helper');15const { assert } = require('playwright/lib/helper');16class Renderer {17 constructor(browser) {18 this._browser = browser;19 this._browserContext = new CRBrowserContext(this._browser._defaultContext);20 this._browserContext._options = {21 };22 }23 async newPage() {24 const page = await Page.create(this._browserContext, null, null, false);25 await page._delegate.initialize();26 return page;27 }28 async close() {29 await this._browserContext.close();30 }31}32module.exports.createRenderer = async () => {33 const browser = await BrowserContext.createBrowser('chromium', {34 });35 return new Renderer(browser);36};37const { CRBrowser } = require('playwright/lib/server/chromium/crBrowser');38const { BrowserContext } = require('playwright/lib/server/browserContext');39const { CRBrowserContext } = require('playwright/lib/server/chromium/crBrowser');40const { assert } = require('playwright/lib/helper');41class CRRendererBrowser extends CRBrowser {42 async _newContextDelegate(options) {43 const context = new CRBrowserContext(this);44 context._options = {
Using AI Code Generation
1const { createRenderer } = require('playwright/lib/server/webkit');2const path = require('path');3const fs = require('fs');4const os = require('os');5const { promisify } = require('util');6const { v4: uuidv4 } = require('uuid');7const writeFileAsync = promisify(fs.writeFile);8const unlinkAsync = promisify(fs.unlink);9(async () => {10 const renderer = await createRenderer();11 const { context } = await renderer.renderToHtml(`<html>12 body {13 background: green;14 }15 </html>`, {16 viewport: {17 },18 });19 const tempFile = path.join(os.tmpdir(), `${uuidv4()}.png`);20 await writeFileAsync(tempFile, context.buffer);21 console.log('See the screenshot at ' + tempFile);22 await unlinkAsync(tempFile);23 await renderer.close();24})();25OS: macOS 11.2.3 (20D91)
Using AI Code Generation
1const { chromium } = require('playwright');2const { createRenderers } = require('playwright/lib/server/browserType');3const { createRenderer } = createRenderers;4(async () => {5 const browser = await chromium.launch();6 const context = await browser.newContext();7 const page = await context.newPage();8 const renderer = await createRenderer(page);9 await renderer.close();10 await browser.close();11})();12const { chromium } = require('playwright');13const { createRenderers } = require('playwright/lib/server/browserType');14const { createRenderer } = createRenderers;15(async () => {16 const browser = await chromium.launch();17 const context = await browser.newContext();18 const page = await context.newPage();19 const renderer = await createRenderer(page);20 await renderer.close();21 await browser.close();22})();23const { chromium } = require('playwright');24const { createRenderers } = require('playwright/lib/server/browserType');25const { createRenderer } = createRenderers;26(async () => {27 const browser = await chromium.launch();28 const context = await browser.newContext();29 const page = await context.newPage();30 const renderer = await createRenderer(page);31 await renderer.close();32 await browser.close();33})();34const { chromium } = require('playwright');35const { createRenderers } = require('playwright/lib/server/browserType');36const { createRenderer } = createRenderers;37(async () => {38 const browser = await chromium.launch();39 const context = await browser.newContext();40 const page = await context.newPage();41 const renderer = await createRenderer(page);42 await renderer.close();43 await browser.close();44})();45const { chromium } = require('playwright');46const { createRenderers } = require('playwright/lib/server/browserType');47const { createRenderer } = create
Using AI Code Generation
1const { createRenderer } = require('playwright-core/lib/server/supplements/recorder/recorderApp');2const renderer = createRenderer();3renderer.render({4 { name: 'click', selector: 'text="I\'m Feeling Lucky"' },5 {6 },7});8const { chromium } = require('playwright');9const { PlaywrightRecorder } = require('playwright-recorder');10(async () => {11 const recorder = new PlaywrightRecorder();12 const browser = await chromium.launch();13 const page = await browser.newPage();14 await recorder.start(page);15 await page.click('text="I\'m Feeling Lucky"');16 await recorder.stop();17})();18#### `PlaywrightRecorder.start(page: Page, options?: { outputDir?: string, fileName?: string, append?: boolean })`19#### `PlaywrightRecorder.stop()`20#### `PlaywrightRecorder.save(options?: { outputDir?: string, fileName?: string, append?: boolean })`21#### `PlaywrightRecorder.getActions()`22#### `PlaywrightRecorder.getActionsAsCode()`23#### `PlaywrightRecorder.getActionsAsCode(options?: { language: 'javascript' | 'typescript' })`24#### `PlaywrightRecorder.getActionsAsCode(options?: { language: 'python'
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!