mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
] Add Fantom test placeholder for LogBox (#49252)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/49252 Changelog: [internal] This adds a Fantom test placeholder for LogBox, which shows what type of tests we could be writing for this. It also adds a few ids in LogBox components so we can inspect them in tests and make assertions on them. Reviewed By: javache Differential Revision: D69301572 fbshipit-source-id: 89a332a47c300c1dc18937cd91206ce6d820b6aa
This commit is contained in:
committed by
Facebook GitHub Bot
parent
b006080949
commit
10e47e69aa
@@ -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 = (
|
||||
<View
|
||||
id={props.id}
|
||||
style={StyleSheet.compose(
|
||||
{
|
||||
backgroundColor: pressed
|
||||
|
||||
@@ -36,7 +36,9 @@ export default function LogBoxInspectorHeader(props: Props): React.Node {
|
||||
<LogBoxInspectorHeaderSafeArea style={styles[props.level]}>
|
||||
<View style={styles.header}>
|
||||
<View style={styles.title}>
|
||||
<Text style={styles.titleText}>Failed to compile</Text>
|
||||
<Text style={styles.titleText} id="logbox_header_title_text">
|
||||
Failed to compile
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</LogBoxInspectorHeaderSafeArea>
|
||||
@@ -60,7 +62,9 @@ export default function LogBoxInspectorHeader(props: Props): React.Node {
|
||||
onPress={() => props.onSelectIndex(prevIndex)}
|
||||
/>
|
||||
<View style={styles.title}>
|
||||
<Text style={styles.titleText}>{titleText}</Text>
|
||||
<Text style={styles.titleText} id="logbox_header_title_text">
|
||||
{titleText}
|
||||
</Text>
|
||||
</View>
|
||||
<LogBoxInspectorHeaderButton
|
||||
disabled={props.total <= 1}
|
||||
|
||||
@@ -46,11 +46,13 @@ function LogBoxInspectorMessageHeader(props: Props): React.Node {
|
||||
return (
|
||||
<View style={messageStyles.body}>
|
||||
<View style={messageStyles.heading}>
|
||||
<Text style={[messageStyles.headingText, messageStyles[props.level]]}>
|
||||
<Text
|
||||
style={[messageStyles.headingText, messageStyles[props.level]]}
|
||||
id="logbox_message_title_text">
|
||||
{props.title}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={messageStyles.bodyText}>
|
||||
<Text style={messageStyles.bodyText} id="logbox_message_contents_text">
|
||||
<LogBoxMessage
|
||||
maxLength={props.collapsed ? SHOW_MORE_MESSAGE_LENGTH : Infinity}
|
||||
message={props.message}
|
||||
|
||||
@@ -39,6 +39,7 @@ export default function LogBoxNotification(props: Props): React.Node {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<LogBoxButton
|
||||
id={`logbox_button_${level}`}
|
||||
onPress={props.onPressOpen}
|
||||
style={styles.press}
|
||||
backgroundColor={{
|
||||
|
||||
+4
@@ -36,6 +36,7 @@ exports[`LogBoxInspectorHeader should render both buttons for two total 1`] = `
|
||||
}
|
||||
>
|
||||
<Text
|
||||
id="logbox_header_title_text"
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
@@ -99,6 +100,7 @@ exports[`LogBoxInspectorHeader should render no buttons for one total 1`] = `
|
||||
}
|
||||
>
|
||||
<Text
|
||||
id="logbox_header_title_text"
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
@@ -152,6 +154,7 @@ exports[`LogBoxInspectorHeader should render syntax error header 1`] = `
|
||||
}
|
||||
>
|
||||
<Text
|
||||
id="logbox_header_title_text"
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
@@ -205,6 +208,7 @@ exports[`LogBoxInspectorHeader should render two buttons for three or more total
|
||||
}
|
||||
>
|
||||
<Text
|
||||
id="logbox_header_title_text"
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
|
||||
+12
@@ -28,6 +28,7 @@ exports[`LogBoxInspectorMessageHeader should not render "See More" if expanded 1
|
||||
}
|
||||
>
|
||||
<Text
|
||||
id="logbox_message_title_text"
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
@@ -47,6 +48,7 @@ exports[`LogBoxInspectorMessageHeader should not render "See More" if expanded 1
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
id="logbox_message_contents_text"
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
@@ -105,6 +107,7 @@ exports[`LogBoxInspectorMessageHeader should not render See More button for shor
|
||||
}
|
||||
>
|
||||
<Text
|
||||
id="logbox_message_title_text"
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
@@ -124,6 +127,7 @@ exports[`LogBoxInspectorMessageHeader should not render See More button for shor
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
id="logbox_message_contents_text"
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
@@ -182,6 +186,7 @@ exports[`LogBoxInspectorMessageHeader should render "See More" if collapsed 1`]
|
||||
}
|
||||
>
|
||||
<Text
|
||||
id="logbox_message_title_text"
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
@@ -201,6 +206,7 @@ exports[`LogBoxInspectorMessageHeader should render "See More" if collapsed 1`]
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
id="logbox_message_contents_text"
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
@@ -272,6 +278,7 @@ exports[`LogBoxInspectorMessageHeader should render error 1`] = `
|
||||
}
|
||||
>
|
||||
<Text
|
||||
id="logbox_message_title_text"
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
@@ -291,6 +298,7 @@ exports[`LogBoxInspectorMessageHeader should render error 1`] = `
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
id="logbox_message_contents_text"
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
@@ -349,6 +357,7 @@ exports[`LogBoxInspectorMessageHeader should render fatal 1`] = `
|
||||
}
|
||||
>
|
||||
<Text
|
||||
id="logbox_message_title_text"
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
@@ -368,6 +377,7 @@ exports[`LogBoxInspectorMessageHeader should render fatal 1`] = `
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
id="logbox_message_contents_text"
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
@@ -426,6 +436,7 @@ exports[`LogBoxInspectorMessageHeader should render syntax error 1`] = `
|
||||
}
|
||||
>
|
||||
<Text
|
||||
id="logbox_message_title_text"
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
@@ -445,6 +456,7 @@ exports[`LogBoxInspectorMessageHeader should render syntax error 1`] = `
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
id="logbox_message_contents_text"
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
|
||||
+1
@@ -20,6 +20,7 @@ exports[`LogBoxNotification should render log 1`] = `
|
||||
"pressed": "rgba(51, 51, 51, 0.9)",
|
||||
}
|
||||
}
|
||||
id="logbox_button_warn"
|
||||
onPress={[Function]}
|
||||
style={
|
||||
Object {
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
* @oncall react_native
|
||||
* @fantom_flags enableAccessToHostTreeInFabric:true
|
||||
*/
|
||||
|
||||
import ensureInstance from '../../../src/private/utilities/ensureInstance';
|
||||
import ReadOnlyElement from '../../../src/private/webapis/dom/nodes/ReadOnlyElement';
|
||||
import View from '../../Components/View/View';
|
||||
import AppContainer from '../../ReactNative/AppContainer';
|
||||
import LogBoxInspectorContainer from '../LogBoxInspectorContainer';
|
||||
import {
|
||||
ManualConsoleError,
|
||||
// $FlowExpectedError[untyped-import]
|
||||
} from './__fixtures__/ReactWarningFixtures';
|
||||
import Fantom from '@react-native/fantom';
|
||||
import nullthrows from 'nullthrows';
|
||||
import * as React from 'react';
|
||||
|
||||
import '../../Core/InitializeCore.js';
|
||||
|
||||
function findById(node: ReadOnlyElement, id: string): ?ReadOnlyElement {
|
||||
if (node.id === id) {
|
||||
return node;
|
||||
}
|
||||
|
||||
for (const child of node.children) {
|
||||
const found = findById(child, id);
|
||||
if (found) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
describe('LogBox', () => {
|
||||
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(<LogBoxInspectorContainer />);
|
||||
});
|
||||
|
||||
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(
|
||||
<View
|
||||
ref={node => {
|
||||
maybeViewNode = node;
|
||||
}}>
|
||||
<LogBoxInspectorContainer />
|
||||
</View>,
|
||||
);
|
||||
});
|
||||
|
||||
expect(logBoxRoot.getRenderedOutput().toJSX()).toBe(null);
|
||||
|
||||
const logBoxRootNode = ensureInstance(maybeViewNode, ReadOnlyElement);
|
||||
|
||||
const root = Fantom.createRoot();
|
||||
Fantom.runTask(() => {
|
||||
root.render(
|
||||
<View
|
||||
ref={node => {
|
||||
maybeViewNode = node;
|
||||
}}>
|
||||
<AppContainer rootTag={root.getRootTag()}>
|
||||
<ManualConsoleError />
|
||||
</AppContainer>
|
||||
</View>,
|
||||
);
|
||||
});
|
||||
|
||||
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');
|
||||
});
|
||||
});
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user