diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxButton.js b/packages/react-native/Libraries/LogBox/UI/LogBoxButton.js
index baaebfe55e3..dfa329b662d 100644
--- a/packages/react-native/Libraries/LogBox/UI/LogBoxButton.js
+++ b/packages/react-native/Libraries/LogBox/UI/LogBoxButton.js
@@ -19,6 +19,7 @@ import * as LogBoxStyle from './LogBoxStyle';
import * as React from 'react';
type Props = $ReadOnly<{
+ id?: string,
backgroundColor: $ReadOnly<{
default: string,
pressed: string,
@@ -42,6 +43,7 @@ function LogBoxButton(props: Props): React.Node {
const content = (
- Failed to compile
+
@@ -60,7 +62,9 @@ export default function LogBoxInspectorHeader(props: Props): React.Node {
onPress={() => props.onSelectIndex(prevIndex)}
/>
- {titleText}
+
-
+
{props.title}
-
+
{
+ let originalConsoleError;
+ let originalConsoleWarn;
+ let mockError;
+ let mockWarn;
+
+ beforeAll(() => {
+ originalConsoleError = console.error;
+ originalConsoleWarn = console.warn;
+ });
+
+ beforeEach(() => {
+ mockError = jest.fn((...args) => {
+ originalConsoleError(...args);
+ });
+ mockWarn = jest.fn((...args) => {
+ originalConsoleWarn(...args);
+ });
+ // $FlowExpectedError[cannot-write]
+ console.error = mockError;
+ // $FlowExpectedError[cannot-write]
+ console.warn = mockWarn;
+ });
+
+ afterEach(() => {
+ // $FlowExpectedError[cannot-write]
+ console.error = originalConsoleError;
+ // $FlowExpectedError[cannot-write]
+ console.warn = originalConsoleWarn;
+ });
+
+ it('renders an empty screen if there are no errors', () => {
+ const logBoxRoot = Fantom.createRoot();
+ Fantom.runTask(() => {
+ logBoxRoot.render();
+ });
+
+ expect(logBoxRoot.getRenderedOutput().toJSX()).toBe(null);
+ });
+
+ it('handles a manual console.error without a component stack in LogBox', () => {
+ let maybeViewNode;
+
+ const logBoxRoot = Fantom.createRoot();
+ Fantom.runTask(() => {
+ logBoxRoot.render(
+ {
+ maybeViewNode = node;
+ }}>
+
+ ,
+ );
+ });
+
+ expect(logBoxRoot.getRenderedOutput().toJSX()).toBe(null);
+
+ const logBoxRootNode = ensureInstance(maybeViewNode, ReadOnlyElement);
+
+ const root = Fantom.createRoot();
+ Fantom.runTask(() => {
+ root.render(
+ {
+ maybeViewNode = node;
+ }}>
+
+
+
+ ,
+ );
+ });
+
+ expect(logBoxRoot.getRenderedOutput().toJSX()).toBe(null);
+
+ const appRootNode = ensureInstance(maybeViewNode, ReadOnlyElement);
+ const logBoxButton = nullthrows(
+ findById(appRootNode, 'logbox_button_error'),
+ );
+
+ Fantom.dispatchNativeEvent(logBoxButton, 'click');
+
+ const headerTitle = findById(logBoxRootNode, 'logbox_header_title_text');
+ const messageTitle = findById(logBoxRootNode, 'logbox_message_title_text');
+ const messageContents = findById(
+ logBoxRootNode,
+ 'logbox_message_contents_text',
+ );
+
+ expect(headerTitle?.textContent).toBe('Log 1 of 1');
+ expect(messageTitle?.textContent).toBe('Console Error');
+ expect(messageContents?.textContent).toBe('Manual console error');
+ });
+});
diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap
index 84f12cb3f45..09e0fdf9a69 100644
--- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap
+++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap
@@ -5480,6 +5480,7 @@ exports[`public API should not change unintentionally Libraries/LogBox/UI/AnsiHi
exports[`public API should not change unintentionally Libraries/LogBox/UI/LogBoxButton.js 1`] = `
"type Props = $ReadOnly<{
+ id?: string,
backgroundColor: $ReadOnly<{
default: string,
pressed: string,