Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 77 additions & 25 deletions src/__tests__/main.test.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,62 @@
import setup from '../index';
import { Component, createRef } from 'react';
import { Component, createRef, useCallback } from 'react';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom';

class WithClickHandler extends Component {
constructor(props) {
super(props);
this.buttonRef = createRef();
}
function makeClassComponent({ addClickHandler, displayName }) {
const onClick = addClickHandler ? () => {} : undefined;

class GeneratedComponent extends Component {
static displayName = displayName;
constructor(props) {
super(props);
this.buttonRef = createRef();
}

componentDidMount() {
this.buttonRef.current.click();
}

componentDidMount() {
this.buttonRef.current.click();
render() {
return <div ref={this.buttonRef} onClick={onClick} />;
}
}

render() {
return <div ref={this.buttonRef} onClick={() => {}} />;
return GeneratedComponent;
}

function clickableDiv(props) {
const ref = useCallback((element) => {
if (element) element.click();
});
return <div {...props} ref={ref} />;
}

function makeFunctionComponent( name, displayName ) {
// we can get the function to use the provided name by mounting it onto an
// object first
const mountedComponent = {
[name](props) {
return clickableDiv(props);
},
};
const GeneratedComponent = mountedComponent[name];

if (displayName) {
GeneratedComponent.displayName = displayName;
}

return GeneratedComponent;
}
WithClickHandler.displayName = 'WithClickHandler';

const WithClickHandler = makeClassComponent({
addClickHandler: true,
displayName: 'WithClickHandler',
});
const NoClickHandler = makeClassComponent({
addClickHandler: false,
displayName: 'NoClickHandler',
});

const NestedA = () => (
<div>
Expand All @@ -43,21 +82,15 @@ const NestedD = () => (
NestedD.displayName = 'NestedD';
NestedD.displayName = 'foobar';

class NoClickHandler extends Component {
constructor(props) {
super(props);
this.buttonRef = createRef();
}

componentDidMount() {
this.buttonRef.current.click();
}
const FunctionComponentWithoutDisplayName = makeFunctionComponent(
'FunctionComponentWithoutDisplayName',
);

render() {
return <div ref={this.buttonRef} />;
}
}
NoClickHandler.displayName = 'NoClickHandler';
// specify both name and displayName here so that we can validate our
// preference for the latter
const FunctionComponentWithDisplayName = makeFunctionComponent(
'FunctionComponentWithDisplayName', 'FCWithDisplayName'
);

describe('logrocket-react', () => {
let clickEvents;
Expand Down Expand Up @@ -102,4 +135,23 @@ describe('logrocket-react', () => {
expect(clickEvents).toHaveLength(1);
expect(clickEvents[0].__lrName).toEqual(['NoClickHandler']);
});

describe('given a function component', function () {
describe('without a display name', function () {
it('it reports the function name instead', function () {
render(<FunctionComponentWithoutDisplayName />);
expect(clickEvents).toHaveLength(1);
expect(clickEvents[0].__lrName).toEqual([
'FunctionComponentWithoutDisplayName',
]);
});
});
describe('with a display name', function () {
it('it reports the display name', function () {
render(<FunctionComponentWithDisplayName />);
expect(clickEvents).toHaveLength(1);
expect(clickEvents[0].__lrName).toEqual(['FCWithDisplayName']);
});
});
});
});
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export default function setupReact() {
while (currentElement) {
var name =
typeof currentElement.elementType === 'function' &&
currentElement.elementType.displayName;
(currentElement.elementType.displayName ||
currentElement.elementType.name);
if (name) {
names.push(name);
}
Expand Down