LogBox - Display errors for notifications and inspector

Summary:
This diff adds and displays errors in LogBox. We will now toast both warnings and errors, open errors for inspection, and allow paginating through errors and warnings.

Changelog: [Internal]

Reviewed By: cpojer

Differential Revision: D18091519

fbshipit-source-id: c155969dc505de5cfb0e95bb5a8221b9f8cfe4f7
This commit is contained in:
Rick Hanlon 2019-10-28 10:08:54 -07:00 коммит произвёл Facebook Github Bot
Родитель c5aa26da41
Коммит 3c525d5b17
13 изменённых файлов: 568 добавлений и 111 удалений

Просмотреть файл

@ -30,13 +30,6 @@ function LogBoxContainer(props: Props): React.Node {
const logs = Array.from(props.logs); const logs = Array.from(props.logs);
function getVisibleLog() {
// TODO: currently returns the newest log but later will need to return
// the newest log of the highest level. For example, we want to show
// the latest error message even if there are newer warnings.
return logs[logs.length - 1];
}
function handleInspectorDismissAll() { function handleInspectorDismissAll() {
props.onDismissAll(); props.onDismissAll();
} }
@ -59,8 +52,12 @@ function LogBoxContainer(props: Props): React.Node {
setSelectedLog(null); setSelectedLog(null);
} }
function handleRowPress(index: number) { function openLog(log: LogBoxLog) {
setSelectedLog(logs.length - 1); let index = logs.length - 1;
while (index > 0 && logs[index] !== log) {
index -= 1;
}
setSelectedLog(index);
} }
if (selectedLogIndex != null) { if (selectedLogIndex != null) {
@ -77,20 +74,42 @@ function LogBoxContainer(props: Props): React.Node {
); );
} }
return logs.length === 0 ? null : ( if (logs.length === 0) {
return null;
}
const warnings = logs.filter(log => log.level === 'warn');
const errors = logs.filter(log => log.level === 'error');
return (
<View style={styles.list}> <View style={styles.list}>
<View style={styles.toast}> {warnings.length > 0 && (
<LogBoxLogNotification <View style={styles.toast}>
log={getVisibleLog()} <LogBoxLogNotification
level="warn" log={warnings[warnings.length - 1]}
totalLogCount={logs.length} level="warn"
onPressOpen={handleRowPress} totalLogCount={warnings.length}
onPressList={() => { onPressOpen={() => openLog(warnings[warnings.length - 1])}
/* TODO: open log list */ onPressList={() => {
}} /* TODO: open log list */
onPressDismiss={handleInspectorDismissAll} }}
/> onPressDismiss={handleInspectorDismissAll}
</View> />
</View>
)}
{errors.length > 0 && (
<View style={styles.toast}>
<LogBoxLogNotification
log={errors[errors.length - 1]}
level="error"
totalLogCount={errors.length}
onPressOpen={() => openLog(errors[errors.length - 1])}
onPressList={() => {
/* TODO: open log list */
}}
onPressDismiss={handleInspectorDismissAll}
/>
</View>
)}
<SafeAreaView style={styles.safeArea} /> <SafeAreaView style={styles.safeArea} />
</View> </View>
); );
@ -105,6 +124,7 @@ const styles = StyleSheet.create({
}, },
toast: { toast: {
borderRadius: 8, borderRadius: 8,
marginBottom: 5,
overflow: 'hidden', overflow: 'hidden',
}, },
safeArea: { safeArea: {

Просмотреть файл

@ -55,6 +55,7 @@ class LogBoxInspector extends React.Component<Props> {
onSelectIndex={this._handleSelectIndex} onSelectIndex={this._handleSelectIndex}
selectedIndex={selectedIndex} selectedIndex={selectedIndex}
total={logs.length} total={logs.length}
level={log.level}
/> />
<LogBoxInspectorBody <LogBoxInspectorBody
log={log} log={log}
@ -113,6 +114,7 @@ function LogBoxInspectorBody(props) {
collapsed={collapsed} collapsed={collapsed}
onPress={() => setCollapsed(!collapsed)} onPress={() => setCollapsed(!collapsed)}
message={props.log.message} message={props.log.message}
level={props.log.level}
/> />
<ScrollView style={styles.scrollBody}> <ScrollView style={styles.scrollBody}>
<LogBoxInspectorReactFrames log={props.log} /> <LogBoxInspectorReactFrames log={props.log} />
@ -128,6 +130,7 @@ function LogBoxInspectorBody(props) {
collapsed={collapsed} collapsed={collapsed}
onPress={() => setCollapsed(!collapsed)} onPress={() => setCollapsed(!collapsed)}
message={props.log.message} message={props.log.message}
level={props.log.level}
/> />
<LogBoxInspectorReactFrames log={props.log} /> <LogBoxInspectorReactFrames log={props.log} />
<LogBoxInspectorStackFrames log={props.log} onRetry={props.onRetry} /> <LogBoxInspectorStackFrames log={props.log} onRetry={props.onRetry} />

Просмотреть файл

@ -20,11 +20,12 @@ import View from '../../Components/View/View';
import LogBoxImageSource from './LogBoxImageSource'; import LogBoxImageSource from './LogBoxImageSource';
import LogBoxButton from './LogBoxButton'; import LogBoxButton from './LogBoxButton';
import * as LogBoxStyle from './LogBoxStyle'; import * as LogBoxStyle from './LogBoxStyle';
import type {LogLevel} from '../Data/LogBoxLog';
type Props = $ReadOnly<{| type Props = $ReadOnly<{|
onSelectIndex: (selectedIndex: number) => void, onSelectIndex: (selectedIndex: number) => void,
selectedIndex: number, selectedIndex: number,
total: number, total: number,
level: LogLevel,
|}>; |}>;
function LogBoxInspectorHeader(props: Props): React.Node { function LogBoxInspectorHeader(props: Props): React.Node {
@ -37,10 +38,11 @@ function LogBoxInspectorHeader(props: Props): React.Node {
: `Log ${props.selectedIndex + 1} of ${props.total}`; : `Log ${props.selectedIndex + 1} of ${props.total}`;
return ( return (
<SafeAreaView style={styles.root}> <SafeAreaView style={styles[props.level]}>
<View style={styles.header}> <View style={styles.header}>
<LogBoxInspectorHeaderButton <LogBoxInspectorHeaderButton
disabled={prevIndex < 0} disabled={prevIndex < 0}
level={props.level}
image={LogBoxImageSource.chevronLeft} image={LogBoxImageSource.chevronLeft}
onPress={() => props.onSelectIndex(prevIndex)} onPress={() => props.onSelectIndex(prevIndex)}
/> />
@ -49,6 +51,7 @@ function LogBoxInspectorHeader(props: Props): React.Node {
</View> </View>
<LogBoxInspectorHeaderButton <LogBoxInspectorHeaderButton
disabled={nextIndex >= props.total} disabled={nextIndex >= props.total}
level={props.level}
image={LogBoxImageSource.chevronRight} image={LogBoxImageSource.chevronRight}
onPress={() => props.onSelectIndex(nextIndex)} onPress={() => props.onSelectIndex(nextIndex)}
/> />
@ -61,14 +64,21 @@ function LogBoxInspectorHeaderButton(
props: $ReadOnly<{| props: $ReadOnly<{|
disabled: boolean, disabled: boolean,
image: string, image: string,
level: LogLevel,
onPress?: ?() => void, onPress?: ?() => void,
|}>, |}>,
): React.Node { ): React.Node {
return ( return (
<LogBoxButton <LogBoxButton
backgroundColor={{ backgroundColor={{
default: LogBoxStyle.getWarningColor(), default:
pressed: LogBoxStyle.getWarningDarkColor(), props.level === 'warn'
? LogBoxStyle.getWarningColor()
: LogBoxStyle.getErrorColor(),
pressed:
props.level === 'warn'
? LogBoxStyle.getWarningDarkColor()
: LogBoxStyle.getErrorDarkColor(),
}} }}
onPress={props.disabled ? null : props.onPress} onPress={props.disabled ? null : props.onPress}
style={headerStyles.button}> style={headerStyles.button}>
@ -99,8 +109,11 @@ const headerStyles = StyleSheet.create({
}); });
const styles = StyleSheet.create({ const styles = StyleSheet.create({
root: { warn: {
backgroundColor: LogBoxStyle.getWarningColor(1), backgroundColor: LogBoxStyle.getWarningColor(),
},
error: {
backgroundColor: LogBoxStyle.getErrorColor(),
}, },
header: { header: {
flexDirection: 'row', flexDirection: 'row',

Просмотреть файл

@ -17,12 +17,13 @@ import View from '../../Components/View/View';
import LogBoxButton from './LogBoxButton'; import LogBoxButton from './LogBoxButton';
import * as LogBoxStyle from './LogBoxStyle'; import * as LogBoxStyle from './LogBoxStyle';
import LogBoxMessage from './LogBoxMessage'; import LogBoxMessage from './LogBoxMessage';
import type {LogLevel} from '../Data/LogBoxLog';
import type {Message} from '../Data/parseLogBoxLog'; import type {Message} from '../Data/parseLogBoxLog';
type Props = $ReadOnly<{| type Props = $ReadOnly<{|
collapsed: boolean, collapsed: boolean,
message: Message, message: Message,
level: LogLevel,
onPress: () => void, onPress: () => void,
|}>; |}>;
@ -49,7 +50,9 @@ function LogBoxInspectorMessageHeader(props: Props): React.Node {
return ( return (
<View style={messageStyles.body}> <View style={messageStyles.body}>
<View style={messageStyles.heading}> <View style={messageStyles.heading}>
<Text style={messageStyles.headingText}>Warning</Text> <Text style={[messageStyles.headingText, messageStyles[props.level]]}>
{props.level === 'warn' ? 'Warning' : 'Error'}
</Text>
{renderShowMore()} {renderShowMore()}
</View> </View>
<Text <Text
@ -91,13 +94,18 @@ const messageStyles = StyleSheet.create({
marginBottom: 5, marginBottom: 5,
}, },
headingText: { headingText: {
color: LogBoxStyle.getWarningColor(1),
flex: 1, flex: 1,
fontSize: 20, fontSize: 20,
fontWeight: '600', fontWeight: '600',
includeFontPadding: false, includeFontPadding: false,
lineHeight: 28, lineHeight: 28,
}, },
warn: {
color: LogBoxStyle.getWarningColor(1),
},
error: {
color: LogBoxStyle.getErrorColor(1),
},
messageText: { messageText: {
color: LogBoxStyle.getTextColor(0.6), color: LogBoxStyle.getTextColor(0.6),
}, },

Просмотреть файл

@ -34,6 +34,10 @@ export function getErrorColor(opacity?: number): string {
return `rgba(243, 83, 105, ${opacity == null ? 1 : opacity})`; return `rgba(243, 83, 105, ${opacity == null ? 1 : opacity})`;
} }
export function getErrorDarkColor(opacity?: number): string {
return `rgba(208, 75, 95, ${opacity == null ? 1 : opacity})`;
}
export function getLogColor(opacity?: number): string { export function getLogColor(opacity?: number): string {
return `rgba(119, 119, 119, ${opacity == null ? 1 : opacity})`; return `rgba(119, 119, 119, ${opacity == null ? 1 : opacity})`;
} }

Просмотреть файл

@ -29,7 +29,7 @@ describe('LogBoxContainer', () => {
expect(output).toMatchSnapshot(); expect(output).toMatchSnapshot();
}); });
it('should render the latest log', () => { it('should render the latest warning', () => {
const output = render.shallowRender( const output = render.shallowRender(
<LogBoxContainer <LogBoxContainer
onDismiss={() => {}} onDismiss={() => {}}
@ -63,4 +63,74 @@ describe('LogBoxContainer', () => {
expect(output).toMatchSnapshot(); expect(output).toMatchSnapshot();
}); });
it('should render the latest error', () => {
const output = render.shallowRender(
<LogBoxContainer
onDismiss={() => {}}
onDismissAll={() => {}}
logs={
new Set([
new LogBoxLog(
'error',
{
content: 'Some kind of message',
substitutions: [],
},
[],
'Some kind of message',
[],
),
new LogBoxLog(
'error',
{
content: 'Some kind of message (latest)',
substitutions: [],
},
[],
'Some kind of message (latest)',
[],
),
])
}
/>,
);
expect(output).toMatchSnapshot();
});
it('should render both an error and warning', () => {
const output = render.shallowRender(
<LogBoxContainer
onDismiss={() => {}}
onDismissAll={() => {}}
logs={
new Set([
new LogBoxLog(
'warn',
{
content: 'Some kind of message',
substitutions: [],
},
[],
'Some kind of message',
[],
),
new LogBoxLog(
'error',
{
content: 'Some kind of message (latest)',
substitutions: [],
},
[],
'Some kind of message (latest)',
[],
),
])
}
/>,
);
expect(output).toMatchSnapshot();
});
}); });

Просмотреть файл

@ -28,7 +28,7 @@ const logs = [
[], [],
), ),
new LogBoxLog( new LogBoxLog(
'warn', 'error',
{ {
content: 'Some kind of message (second)', content: 'Some kind of message (second)',
substitutions: [], substitutions: [],
@ -54,7 +54,7 @@ describe('LogBoxContainer', () => {
expect(output).toMatchSnapshot(); expect(output).toMatchSnapshot();
}); });
it('should render first log with selectedIndex 0', () => { it('should render warning with selectedIndex 0', () => {
const output = render.shallowRender( const output = render.shallowRender(
<LogBoxInspector <LogBoxInspector
onDismiss={() => {}} onDismiss={() => {}}
@ -68,7 +68,7 @@ describe('LogBoxContainer', () => {
expect(output).toMatchSnapshot(); expect(output).toMatchSnapshot();
}); });
it('should render second log with selectedIndex 1', () => { it('should render error with selectedIndex 1', () => {
const output = render.shallowRender( const output = render.shallowRender(
<LogBoxInspector <LogBoxInspector
onDismiss={() => {}} onDismiss={() => {}}

Просмотреть файл

@ -22,6 +22,7 @@ describe('LogBoxInspectorHeader', () => {
onSelectIndex={() => {}} onSelectIndex={() => {}}
selectedIndex={0} selectedIndex={0}
total={1} total={1}
level="warn"
/>, />,
); );
@ -34,18 +35,33 @@ describe('LogBoxInspectorHeader', () => {
onSelectIndex={() => {}} onSelectIndex={() => {}}
selectedIndex={1} selectedIndex={1}
total={2} total={2}
level="warn"
/>, />,
); );
expect(output).toMatchSnapshot(); expect(output).toMatchSnapshot();
}); });
it('should render two buttons for three total, middle selected', () => { it('should render two buttons for three total, middle selected (warning)', () => {
const output = render.shallowRender( const output = render.shallowRender(
<LogBoxInspectorHeader <LogBoxInspectorHeader
onSelectIndex={() => {}} onSelectIndex={() => {}}
selectedIndex={0} selectedIndex={0}
total={1} total={1}
level="warn"
/>,
);
expect(output).toMatchSnapshot();
});
it('should render two buttons for three total, middle selected (error)', () => {
const output = render.shallowRender(
<LogBoxInspectorHeader
onSelectIndex={() => {}}
selectedIndex={0}
total={1}
level="error"
/>, />,
); );
@ -58,6 +74,7 @@ describe('LogBoxInspectorHeader', () => {
onSelectIndex={() => {}} onSelectIndex={() => {}}
selectedIndex={0} selectedIndex={0}
total={2} total={2}
level="warn"
/>, />,
); );

Просмотреть файл

@ -17,9 +17,26 @@ const LogBoxInspectorMessageHeader = require('../LogBoxInspectorMessageHeader')
const render = require('../../../../jest/renderer'); const render = require('../../../../jest/renderer');
describe('LogBoxInspectorMessageHeader', () => { describe('LogBoxInspectorMessageHeader', () => {
it('should not render error', () => {
const output = render.shallowRender(
<LogBoxInspectorMessageHeader
level="error"
collapsed={false}
message={{
content: 'Short',
substitutions: [],
}}
onPress={() => {}}
/>,
);
expect(output).toMatchSnapshot();
});
it('should not render collapse button for short content', () => { it('should not render collapse button for short content', () => {
const output = render.shallowRender( const output = render.shallowRender(
<LogBoxInspectorMessageHeader <LogBoxInspectorMessageHeader
level="warn"
collapsed={false} collapsed={false}
message={{ message={{
content: 'Short', content: 'Short',
@ -35,6 +52,7 @@ describe('LogBoxInspectorMessageHeader', () => {
it('should render "collapse" if expanded', () => { it('should render "collapse" if expanded', () => {
const output = render.shallowRender( const output = render.shallowRender(
<LogBoxInspectorMessageHeader <LogBoxInspectorMessageHeader
level="warn"
collapsed={false} collapsed={false}
message={{content: '#'.repeat(200), substitutions: []}} message={{content: '#'.repeat(200), substitutions: []}}
onPress={() => {}} onPress={() => {}}
@ -47,6 +65,7 @@ describe('LogBoxInspectorMessageHeader', () => {
it('should render "see more" if collapsed', () => { it('should render "see more" if collapsed', () => {
const output = render.shallowRender( const output = render.shallowRender(
<LogBoxInspectorMessageHeader <LogBoxInspectorMessageHeader
level="warn"
collapsed={true} collapsed={true}
message={{ message={{
content: '#'.repeat(200), content: '#'.repeat(200),

Просмотреть файл

@ -1,8 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`LogBoxContainer should render null with no logs 1`] = `null`; exports[`LogBoxContainer should render both an error and warning 1`] = `
exports[`LogBoxContainer should render the latest log 1`] = `
<View <View
style={ style={
Object { Object {
@ -17,6 +15,156 @@ exports[`LogBoxContainer should render the latest log 1`] = `
style={ style={
Object { Object {
"borderRadius": 8, "borderRadius": 8,
"marginBottom": 5,
"overflow": "hidden",
}
}
>
<LogBoxLogNotification
level="warn"
log={
LogBoxLog {
"category": "Some kind of message",
"componentStack": Array [],
"count": 1,
"level": "warn",
"message": Object {
"content": "Some kind of message",
"substitutions": Array [],
},
"stack": Array [],
"symbolicated": Object {
"error": null,
"stack": null,
"status": "NONE",
},
}
}
onPressDismiss={[Function]}
onPressList={[Function]}
onPressOpen={[Function]}
totalLogCount={1}
/>
</View>
<View
style={
Object {
"borderRadius": 8,
"marginBottom": 5,
"overflow": "hidden",
}
}
>
<LogBoxLogNotification
level="error"
log={
LogBoxLog {
"category": "Some kind of message (latest)",
"componentStack": Array [],
"count": 1,
"level": "error",
"message": Object {
"content": "Some kind of message (latest)",
"substitutions": Array [],
},
"stack": Array [],
"symbolicated": Object {
"error": null,
"stack": null,
"status": "NONE",
},
}
}
onPressDismiss={[Function]}
onPressList={[Function]}
onPressOpen={[Function]}
totalLogCount={1}
/>
</View>
<ForwardRef(SafeAreaView)
style={
Object {
"flex": 1,
}
}
/>
</View>
`;
exports[`LogBoxContainer should render null with no logs 1`] = `null`;
exports[`LogBoxContainer should render the latest error 1`] = `
<View
style={
Object {
"bottom": 10,
"left": 10,
"position": "absolute",
"right": 10,
}
}
>
<View
style={
Object {
"borderRadius": 8,
"marginBottom": 5,
"overflow": "hidden",
}
}
>
<LogBoxLogNotification
level="error"
log={
LogBoxLog {
"category": "Some kind of message (latest)",
"componentStack": Array [],
"count": 1,
"level": "error",
"message": Object {
"content": "Some kind of message (latest)",
"substitutions": Array [],
},
"stack": Array [],
"symbolicated": Object {
"error": null,
"stack": null,
"status": "NONE",
},
}
}
onPressDismiss={[Function]}
onPressList={[Function]}
onPressOpen={[Function]}
totalLogCount={2}
/>
</View>
<ForwardRef(SafeAreaView)
style={
Object {
"flex": 1,
}
}
/>
</View>
`;
exports[`LogBoxContainer should render the latest warning 1`] = `
<View
style={
Object {
"bottom": 10,
"left": 10,
"position": "absolute",
"right": 10,
}
}
>
<View
style={
Object {
"borderRadius": 8,
"marginBottom": 5,
"overflow": "hidden", "overflow": "hidden",
} }
} }

Просмотреть файл

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`LogBoxContainer should render first log with selectedIndex 0 1`] = ` exports[`LogBoxContainer should render error with selectedIndex 1 1`] = `
<View <View
style={ style={
Object { Object {
@ -11,6 +11,53 @@ exports[`LogBoxContainer should render first log with selectedIndex 0 1`] = `
} }
> >
<LogBoxInspectorHeader <LogBoxInspectorHeader
level="error"
onSelectIndex={[Function]}
selectedIndex={1}
total={2}
/>
<LogBoxInspectorBody
log={
LogBoxLog {
"category": "Some kind of message (second)",
"componentStack": Array [],
"count": 1,
"level": "error",
"message": Object {
"content": "Some kind of message (second)",
"substitutions": Array [],
},
"stack": Array [],
"symbolicated": Object {
"error": null,
"stack": null,
"status": "NONE",
},
}
}
onRetry={[Function]}
/>
<LogBoxInspectorFooter
onDismiss={[Function]}
onMinimize={[Function]}
/>
</View>
`;
exports[`LogBoxContainer should render null with no logs 1`] = `null`;
exports[`LogBoxContainer should render warning with selectedIndex 0 1`] = `
<View
style={
Object {
"backgroundColor": "rgba(255, 255, 255, 1)",
"elevation": undefined,
"height": "100%",
}
}
>
<LogBoxInspectorHeader
level="warn"
onSelectIndex={[Function]} onSelectIndex={[Function]}
selectedIndex={0} selectedIndex={0}
total={2} total={2}
@ -42,48 +89,3 @@ exports[`LogBoxContainer should render first log with selectedIndex 0 1`] = `
/> />
</View> </View>
`; `;
exports[`LogBoxContainer should render null with no logs 1`] = `null`;
exports[`LogBoxContainer should render second log with selectedIndex 1 1`] = `
<View
style={
Object {
"backgroundColor": "rgba(255, 255, 255, 1)",
"elevation": undefined,
"height": "100%",
}
}
>
<LogBoxInspectorHeader
onSelectIndex={[Function]}
selectedIndex={1}
total={2}
/>
<LogBoxInspectorBody
log={
LogBoxLog {
"category": "Some kind of message (second)",
"componentStack": Array [],
"count": 1,
"level": "warn",
"message": Object {
"content": "Some kind of message (second)",
"substitutions": Array [],
},
"stack": Array [],
"symbolicated": Object {
"error": null,
"stack": null,
"status": "NONE",
},
}
}
onRetry={[Function]}
/>
<LogBoxInspectorFooter
onDismiss={[Function]}
onMinimize={[Function]}
/>
</View>
`;

Просмотреть файл

@ -19,6 +19,7 @@ exports[`LogBoxInspectorHeader should render no buttons for one total 1`] = `
<LogBoxInspectorHeaderButton <LogBoxInspectorHeaderButton
disabled={true} disabled={true}
image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAaUlEQVRYhe3WsQ2AMAwAwRcs5LEYg3HpYANoQKKgcEEUI/6adM5LbgySfmZsNDeACdiApdEfaQGswH6+Xd1jugc9xYQxxhjz9RhaxwxvDuul3MrAqDyjsozKKnWgXUqdsJcAZgqsTFJ5B7gjUNw0n0HHAAAAAElFTkSuQmCC" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAaUlEQVRYhe3WsQ2AMAwAwRcs5LEYg3HpYANoQKKgcEEUI/6adM5LbgySfmZsNDeACdiApdEfaQGswH6+Xd1jugc9xYQxxhjz9RhaxwxvDuul3MrAqDyjsozKKnWgXUqdsJcAZgqsTFJ5B7gjUNw0n0HHAAAAAElFTkSuQmCC"
level="warn"
onPress={[Function]} onPress={[Function]}
/> />
<View <View
@ -47,6 +48,7 @@ exports[`LogBoxInspectorHeader should render no buttons for one total 1`] = `
<LogBoxInspectorHeaderButton <LogBoxInspectorHeaderButton
disabled={true} disabled={true}
image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAZElEQVRYhe3WsQmAQAxA0Y8ulLEcw3HtdANtBNvzCJjD/5pUgQ9pApJ+Zu7YCWABDmDLzemzA+c94+MW4AkqExUY1caoVka1GibqlSm7qJJSJzPGGGMylYqBgi9sACtFYiQN7wKC6VDcJ7tlpQAAAABJRU5ErkJggg==" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAZElEQVRYhe3WsQmAQAxA0Y8ulLEcw3HtdANtBNvzCJjD/5pUgQ9pApJ+Zu7YCWABDmDLzemzA+c94+MW4AkqExUY1caoVka1GibqlSm7qJJSJzPGGGMylYqBgi9sACtFYiQN7wKC6VDcJ7tlpQAAAABJRU5ErkJggg=="
level="warn"
onPress={[Function]} onPress={[Function]}
/> />
</View> </View>
@ -72,6 +74,7 @@ exports[`LogBoxInspectorHeader should render one left button for two total, righ
<LogBoxInspectorHeaderButton <LogBoxInspectorHeaderButton
disabled={false} disabled={false}
image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAaUlEQVRYhe3WsQ2AMAwAwRcs5LEYg3HpYANoQKKgcEEUI/6adM5LbgySfmZsNDeACdiApdEfaQGswH6+Xd1jugc9xYQxxhjz9RhaxwxvDuul3MrAqDyjsozKKnWgXUqdsJcAZgqsTFJ5B7gjUNw0n0HHAAAAAElFTkSuQmCC" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAaUlEQVRYhe3WsQ2AMAwAwRcs5LEYg3HpYANoQKKgcEEUI/6adM5LbgySfmZsNDeACdiApdEfaQGswH6+Xd1jugc9xYQxxhjz9RhaxwxvDuul3MrAqDyjsozKKnWgXUqdsJcAZgqsTFJ5B7gjUNw0n0HHAAAAAElFTkSuQmCC"
level="warn"
onPress={[Function]} onPress={[Function]}
/> />
<View <View
@ -100,6 +103,7 @@ exports[`LogBoxInspectorHeader should render one left button for two total, righ
<LogBoxInspectorHeaderButton <LogBoxInspectorHeaderButton
disabled={true} disabled={true}
image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAZElEQVRYhe3WsQmAQAxA0Y8ulLEcw3HtdANtBNvzCJjD/5pUgQ9pApJ+Zu7YCWABDmDLzemzA+c94+MW4AkqExUY1caoVka1GibqlSm7qJJSJzPGGGMylYqBgi9sACtFYiQN7wKC6VDcJ7tlpQAAAABJRU5ErkJggg==" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAZElEQVRYhe3WsQmAQAxA0Y8ulLEcw3HtdANtBNvzCJjD/5pUgQ9pApJ+Zu7YCWABDmDLzemzA+c94+MW4AkqExUY1caoVka1GibqlSm7qJJSJzPGGGMylYqBgi9sACtFYiQN7wKC6VDcJ7tlpQAAAABJRU5ErkJggg=="
level="warn"
onPress={[Function]} onPress={[Function]}
/> />
</View> </View>
@ -125,6 +129,7 @@ exports[`LogBoxInspectorHeader should render one right button for two total, lef
<LogBoxInspectorHeaderButton <LogBoxInspectorHeaderButton
disabled={true} disabled={true}
image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAaUlEQVRYhe3WsQ2AMAwAwRcs5LEYg3HpYANoQKKgcEEUI/6adM5LbgySfmZsNDeACdiApdEfaQGswH6+Xd1jugc9xYQxxhjz9RhaxwxvDuul3MrAqDyjsozKKnWgXUqdsJcAZgqsTFJ5B7gjUNw0n0HHAAAAAElFTkSuQmCC" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAaUlEQVRYhe3WsQ2AMAwAwRcs5LEYg3HpYANoQKKgcEEUI/6adM5LbgySfmZsNDeACdiApdEfaQGswH6+Xd1jugc9xYQxxhjz9RhaxwxvDuul3MrAqDyjsozKKnWgXUqdsJcAZgqsTFJ5B7gjUNw0n0HHAAAAAElFTkSuQmCC"
level="warn"
onPress={[Function]} onPress={[Function]}
/> />
<View <View
@ -153,17 +158,18 @@ exports[`LogBoxInspectorHeader should render one right button for two total, lef
<LogBoxInspectorHeaderButton <LogBoxInspectorHeaderButton
disabled={false} disabled={false}
image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAZElEQVRYhe3WsQmAQAxA0Y8ulLEcw3HtdANtBNvzCJjD/5pUgQ9pApJ+Zu7YCWABDmDLzemzA+c94+MW4AkqExUY1caoVka1GibqlSm7qJJSJzPGGGMylYqBgi9sACtFYiQN7wKC6VDcJ7tlpQAAAABJRU5ErkJggg==" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAZElEQVRYhe3WsQmAQAxA0Y8ulLEcw3HtdANtBNvzCJjD/5pUgQ9pApJ+Zu7YCWABDmDLzemzA+c94+MW4AkqExUY1caoVka1GibqlSm7qJJSJzPGGGMylYqBgi9sACtFYiQN7wKC6VDcJ7tlpQAAAABJRU5ErkJggg=="
level="warn"
onPress={[Function]} onPress={[Function]}
/> />
</View> </View>
</ForwardRef(SafeAreaView)> </ForwardRef(SafeAreaView)>
`; `;
exports[`LogBoxInspectorHeader should render two buttons for three total, middle selected 1`] = ` exports[`LogBoxInspectorHeader should render two buttons for three total, middle selected (error) 1`] = `
<ForwardRef(SafeAreaView) <ForwardRef(SafeAreaView)
style={ style={
Object { Object {
"backgroundColor": "rgba(250, 186, 48, 1)", "backgroundColor": "rgba(243, 83, 105, 1)",
} }
} }
> >
@ -178,6 +184,7 @@ exports[`LogBoxInspectorHeader should render two buttons for three total, middle
<LogBoxInspectorHeaderButton <LogBoxInspectorHeaderButton
disabled={true} disabled={true}
image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAaUlEQVRYhe3WsQ2AMAwAwRcs5LEYg3HpYANoQKKgcEEUI/6adM5LbgySfmZsNDeACdiApdEfaQGswH6+Xd1jugc9xYQxxhjz9RhaxwxvDuul3MrAqDyjsozKKnWgXUqdsJcAZgqsTFJ5B7gjUNw0n0HHAAAAAElFTkSuQmCC" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAaUlEQVRYhe3WsQ2AMAwAwRcs5LEYg3HpYANoQKKgcEEUI/6adM5LbgySfmZsNDeACdiApdEfaQGswH6+Xd1jugc9xYQxxhjz9RhaxwxvDuul3MrAqDyjsozKKnWgXUqdsJcAZgqsTFJ5B7gjUNw0n0HHAAAAAElFTkSuQmCC"
level="error"
onPress={[Function]} onPress={[Function]}
/> />
<View <View
@ -206,6 +213,62 @@ exports[`LogBoxInspectorHeader should render two buttons for three total, middle
<LogBoxInspectorHeaderButton <LogBoxInspectorHeaderButton
disabled={true} disabled={true}
image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAZElEQVRYhe3WsQmAQAxA0Y8ulLEcw3HtdANtBNvzCJjD/5pUgQ9pApJ+Zu7YCWABDmDLzemzA+c94+MW4AkqExUY1caoVka1GibqlSm7qJJSJzPGGGMylYqBgi9sACtFYiQN7wKC6VDcJ7tlpQAAAABJRU5ErkJggg==" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAZElEQVRYhe3WsQmAQAxA0Y8ulLEcw3HtdANtBNvzCJjD/5pUgQ9pApJ+Zu7YCWABDmDLzemzA+c94+MW4AkqExUY1caoVka1GibqlSm7qJJSJzPGGGMylYqBgi9sACtFYiQN7wKC6VDcJ7tlpQAAAABJRU5ErkJggg=="
level="error"
onPress={[Function]}
/>
</View>
</ForwardRef(SafeAreaView)>
`;
exports[`LogBoxInspectorHeader should render two buttons for three total, middle selected (warning) 1`] = `
<ForwardRef(SafeAreaView)
style={
Object {
"backgroundColor": "rgba(250, 186, 48, 1)",
}
}
>
<View
style={
Object {
"flexDirection": "row",
"height": 44,
}
}
>
<LogBoxInspectorHeaderButton
disabled={true}
image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAaUlEQVRYhe3WsQ2AMAwAwRcs5LEYg3HpYANoQKKgcEEUI/6adM5LbgySfmZsNDeACdiApdEfaQGswH6+Xd1jugc9xYQxxhjz9RhaxwxvDuul3MrAqDyjsozKKnWgXUqdsJcAZgqsTFJ5B7gjUNw0n0HHAAAAAElFTkSuQmCC"
level="warn"
onPress={[Function]}
/>
<View
style={
Object {
"alignItems": "center",
"flex": 1,
"justifyContent": "center",
}
}
>
<Text
style={
Object {
"color": "rgba(255, 255, 255, 1)",
"fontSize": 16,
"fontWeight": "600",
"includeFontPadding": false,
"lineHeight": 20,
}
}
>
Log
</Text>
</View>
<LogBoxInspectorHeaderButton
disabled={true}
image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAZElEQVRYhe3WsQmAQAxA0Y8ulLEcw3HtdANtBNvzCJjD/5pUgQ9pApJ+Zu7YCWABDmDLzemzA+c94+MW4AkqExUY1caoVka1GibqlSm7qJJSJzPGGGMylYqBgi9sACtFYiQN7wKC6VDcJ7tlpQAAAABJRU5ErkJggg=="
level="warn"
onPress={[Function]} onPress={[Function]}
/> />
</View> </View>

Просмотреть файл

@ -30,14 +30,18 @@ exports[`LogBoxInspectorMessageHeader should not render collapse button for shor
> >
<Text <Text
style={ style={
Object { Array [
"color": "rgba(250, 186, 48, 1)", Object {
"flex": 1, "flex": 1,
"fontSize": 20, "fontSize": 20,
"fontWeight": "600", "fontWeight": "600",
"includeFontPadding": false, "includeFontPadding": false,
"lineHeight": 28, "lineHeight": 28,
} },
Object {
"color": "rgba(250, 186, 48, 1)",
},
]
} }
> >
Warning Warning
@ -74,6 +78,84 @@ exports[`LogBoxInspectorMessageHeader should not render collapse button for shor
</View> </View>
`; `;
exports[`LogBoxInspectorMessageHeader should not render error 1`] = `
<View
style={
Object {
"backgroundColor": "rgba(51, 51, 51, 1)",
"elevation": 2,
"flex": 0,
"shadowColor": "#000",
"shadowOffset": Object {
"height": 2,
"width": 0,
},
"shadowOpacity": 0.5,
"shadowRadius": 2,
}
}
>
<View
style={
Object {
"alignItems": "center",
"flexDirection": "row",
"marginBottom": 5,
"marginTop": 10,
"paddingHorizontal": 12,
}
}
>
<Text
style={
Array [
Object {
"flex": 1,
"fontSize": 20,
"fontWeight": "600",
"includeFontPadding": false,
"lineHeight": 28,
},
Object {
"color": "rgba(243, 83, 105, 1)",
},
]
}
>
Error
</Text>
</View>
<Text
numberOfLines={null}
style={
Object {
"color": "rgba(255, 255, 255, 1)",
"fontSize": 14,
"fontWeight": "500",
"includeFontPadding": false,
"lineHeight": 20,
"paddingBottom": 10,
"paddingHorizontal": 12,
}
}
>
<LogBoxMessage
message={
Object {
"content": "Short",
"substitutions": Array [],
}
}
style={
Object {
"color": "rgba(255, 255, 255, 0.6)",
}
}
/>
</Text>
</View>
`;
exports[`LogBoxInspectorMessageHeader should render "collapse" if expanded 1`] = ` exports[`LogBoxInspectorMessageHeader should render "collapse" if expanded 1`] = `
<View <View
style={ style={
@ -104,14 +186,18 @@ exports[`LogBoxInspectorMessageHeader should render "collapse" if expanded 1`] =
> >
<Text <Text
style={ style={
Object { Array [
"color": "rgba(250, 186, 48, 1)", Object {
"flex": 1, "flex": 1,
"fontSize": 20, "fontSize": 20,
"fontWeight": "600", "fontWeight": "600",
"includeFontPadding": false, "includeFontPadding": false,
"lineHeight": 28, "lineHeight": 28,
} },
Object {
"color": "rgba(250, 186, 48, 1)",
},
]
} }
> >
Warning Warning
@ -207,14 +293,18 @@ exports[`LogBoxInspectorMessageHeader should render "see more" if collapsed 1`]
> >
<Text <Text
style={ style={
Object { Array [
"color": "rgba(250, 186, 48, 1)", Object {
"flex": 1, "flex": 1,
"fontSize": 20, "fontSize": 20,
"fontWeight": "600", "fontWeight": "600",
"includeFontPadding": false, "includeFontPadding": false,
"lineHeight": 28, "lineHeight": 28,
} },
Object {
"color": "rgba(250, 186, 48, 1)",
},
]
} }
> >
Warning Warning