mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add the ability for tests to be marked as 'skipped'
Summary: Changelog: [RNTester][Internal] - Add the ability for platform tests to be marked as skipped There are some properties/tests in the web platform tests that we don't want to especially priorities (especially if they aren't especially relevant to the specification and just legacy browser compat) so this adds the ability for us to mark these tests as skipped. This is so that we can ensure that our platform tests are "complete" while decreasing the noise and distraction from failing tests that don't really apply to RN. Reviewed By: lunaleaps Differential Revision: D37889470 fbshipit-source-id: 6516ac90c242d662518a95cb9ba8ce643f6bb09c
This commit is contained in:
committed by
Facebook GitHub Bot
parent
966f800b7c
commit
663dd9177e
@@ -24,7 +24,7 @@ function ExampleTestCase ({ harness }) { /* ... */ }
|
||||
|
||||
As of writting this README there are 2 different types of tests that the `harness` prop provides:
|
||||
|
||||
### `test(testcase: (TestContext) => void, testName: string)`
|
||||
### `test(testcase: (TestContext) => void, testName: string, options?: TestOptions)`
|
||||
|
||||
This is a method to create "regular" test reminicent of other frameworks such as Jest. These are meant to be run imperatively, and while that means that they technically could work in a `useEffect` hook as a way to run the test "on mount" — it is instead recommended to try and keep these tests in callbacks instead. A good alternative to running the test on mount would be to instead put the test in a callback and render a "Start Test" button which executes the callback.
|
||||
|
||||
@@ -35,6 +35,10 @@ The first argument is the closure in which you will run your test and make asser
|
||||
* `assert_greater_than_equal(a: number, b: number, description: string): void`
|
||||
* `assert_less_than_equal(a: number, b: number, description: string): void`
|
||||
|
||||
An optional third argument can be used for specifying additional options to the test — that object currently has the following properties (all of which are optional themselves):
|
||||
|
||||
* `skip: boolean`: In cases where we want the test to be registered but we don't want it to contribute to the pass/fail count.
|
||||
|
||||
Here's what a basic/contrived example which verifies the layout of a basic view:
|
||||
|
||||
```js
|
||||
|
||||
+13
-28
@@ -10,6 +10,8 @@
|
||||
|
||||
import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
|
||||
|
||||
import RNTesterPlatformTestResultsText from './RNTesterPlatformTestResultsText';
|
||||
|
||||
import * as React from 'react';
|
||||
import {View, Text, StyleSheet, TouchableHighlight} from 'react-native';
|
||||
|
||||
@@ -18,6 +20,7 @@ type Props = $ReadOnly<{|
|
||||
numError: number,
|
||||
numPass: number,
|
||||
numPending: number,
|
||||
numSkipped: number,
|
||||
onPress?: () => void,
|
||||
style?: ?ViewStyleProp,
|
||||
|}>;
|
||||
@@ -26,26 +29,22 @@ export default function RNTesterPlatformTestMinimizedResultView({
|
||||
numError,
|
||||
numPass,
|
||||
numPending,
|
||||
numSkipped,
|
||||
onPress,
|
||||
style,
|
||||
}: Props): React.MixedElement {
|
||||
return (
|
||||
<TouchableHighlight onPress={onPress} style={[styles.root, style]}>
|
||||
<View style={styles.innerContainer}>
|
||||
<View style={styles.statsContainer}>
|
||||
<Text style={styles.summaryText}>
|
||||
{numPass} <Text style={styles.passText}>Pass</Text>
|
||||
</Text>
|
||||
<Text style={styles.summaryText}>
|
||||
{numFail} <Text style={styles.failText}>Fail</Text>
|
||||
</Text>
|
||||
<Text style={styles.summaryText}>
|
||||
{numError} <Text style={styles.errorText}>Error</Text>
|
||||
</Text>
|
||||
<Text style={styles.summaryText}>
|
||||
{numPending} <Text style={styles.pendingText}>Pending</Text>
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.statsContainer}>
|
||||
<RNTesterPlatformTestResultsText
|
||||
numError={numError}
|
||||
numFail={numFail}
|
||||
numPass={numPass}
|
||||
numPending={numPending}
|
||||
numSkipped={numSkipped}
|
||||
/>
|
||||
</Text>
|
||||
<Text style={styles.caret}>⌃</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
@@ -59,12 +58,6 @@ const styles = StyleSheet.create({
|
||||
marginEnd: 8,
|
||||
opacity: 0.5,
|
||||
},
|
||||
errorText: {
|
||||
color: 'orange',
|
||||
},
|
||||
failText: {
|
||||
color: 'red',
|
||||
},
|
||||
innerContainer: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
@@ -74,12 +67,6 @@ const styles = StyleSheet.create({
|
||||
paddingHorizontal: 8,
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
passText: {
|
||||
color: 'green',
|
||||
},
|
||||
pendingText: {
|
||||
color: 'gray',
|
||||
},
|
||||
root: {
|
||||
borderTopColor: 'rgb(171, 171, 171)',
|
||||
borderTopWidth: StyleSheet.hairlineWidth,
|
||||
@@ -89,8 +76,6 @@ const styles = StyleSheet.create({
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
},
|
||||
summaryText: {
|
||||
marginStart: 8,
|
||||
},
|
||||
});
|
||||
|
||||
+18
-21
@@ -19,6 +19,7 @@ import type {
|
||||
} from './RNTesterPlatformTestTypes';
|
||||
|
||||
import RNTesterPlatformTestMinimizedResultView from './RNTesterPlatformTestMinimizedResultView';
|
||||
import RNTesterPlatformTestResultsText from './RNTesterPlatformTestResultsText';
|
||||
|
||||
import * as React from 'react';
|
||||
import {useMemo, useState, useCallback} from 'react';
|
||||
@@ -40,6 +41,7 @@ const DISPLAY_STATUS_MAPPING: {[PlatformTestResultStatus]: string} = {
|
||||
PASS: 'Pass',
|
||||
FAIL: 'Fail',
|
||||
ERROR: 'Error',
|
||||
SKIPPED: 'Skipped',
|
||||
};
|
||||
|
||||
type FilterModalProps = $ReadOnly<{
|
||||
@@ -183,7 +185,7 @@ export default function RNTesterPlatformTestResultView(
|
||||
);
|
||||
}, [filterText, results]);
|
||||
|
||||
const {numPass, numFail, numError} = useMemo(
|
||||
const {numPass, numFail, numError, numSkipped} = useMemo(
|
||||
() =>
|
||||
filteredResults.reduce(
|
||||
(acc, result) => {
|
||||
@@ -194,12 +196,15 @@ export default function RNTesterPlatformTestResultView(
|
||||
return {...acc, numFail: acc.numFail + 1};
|
||||
case 'ERROR':
|
||||
return {...acc, numError: acc.numError + 1};
|
||||
case 'SKIPPED':
|
||||
return {...acc, numSkipped: acc.numSkipped + 1};
|
||||
}
|
||||
},
|
||||
{
|
||||
numPass: 0,
|
||||
numFail: 0,
|
||||
numError: 0,
|
||||
numSkipped: 0,
|
||||
},
|
||||
),
|
||||
[filteredResults],
|
||||
@@ -228,6 +233,7 @@ export default function RNTesterPlatformTestResultView(
|
||||
numError={numError}
|
||||
numPass={numPass}
|
||||
numPending={numPending}
|
||||
numSkipped={numSkipped}
|
||||
onPress={handleMinimizedPress}
|
||||
style={style}
|
||||
/>
|
||||
@@ -250,26 +256,13 @@ export default function RNTesterPlatformTestResultView(
|
||||
</Text>
|
||||
) : null}
|
||||
<Text style={styles.summaryContainer}>
|
||||
<Text>
|
||||
{numPass} <Text style={styles.passText}>Pass</Text>
|
||||
</Text>
|
||||
{' '}
|
||||
<Text>
|
||||
{numFail} <Text style={styles.failText}>Fail</Text>
|
||||
</Text>
|
||||
{' '}
|
||||
<Text>
|
||||
{numError} <Text style={styles.errorText}>Error</Text>
|
||||
</Text>
|
||||
{numPending > 0 ? (
|
||||
<>
|
||||
{' '}
|
||||
<Text>
|
||||
{numPending}{' '}
|
||||
<Text style={styles.pendingText}>Pending</Text>
|
||||
</Text>
|
||||
</>
|
||||
) : null}
|
||||
<RNTesterPlatformTestResultsText
|
||||
numError={numError}
|
||||
numFail={numFail}
|
||||
numPass={numPass}
|
||||
numPending={numPending}
|
||||
numSkipped={numSkipped}
|
||||
/>
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.actionsContainer}>
|
||||
@@ -399,6 +392,9 @@ const styles = StyleSheet.create({
|
||||
paddingTop: 8,
|
||||
flex: 0,
|
||||
},
|
||||
skippedText: {
|
||||
color: 'blue',
|
||||
},
|
||||
table: {
|
||||
flex: 1,
|
||||
},
|
||||
@@ -446,4 +442,5 @@ const STATUS_TEXT_STYLE_MAPPING: {[PlatformTestResultStatus]: TextStyle} = {
|
||||
PASS: styles.passText,
|
||||
FAIL: styles.failText,
|
||||
ERROR: styles.errorText,
|
||||
SKIPPED: styles.skippedText,
|
||||
};
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import {Text, StyleSheet} from 'react-native';
|
||||
import * as React from 'react';
|
||||
|
||||
type Props = $ReadOnly<{
|
||||
numPass: number,
|
||||
numFail: number,
|
||||
numError: number,
|
||||
numPending: number,
|
||||
numSkipped: number,
|
||||
}>;
|
||||
export default function RNTesterPlatformTestResultsText(
|
||||
props: Props,
|
||||
): React.MixedElement {
|
||||
const {numPass, numFail, numError, numPending, numSkipped} = props;
|
||||
return (
|
||||
<>
|
||||
<Text>
|
||||
{numPass} <Text style={styles.passText}>Pass</Text>
|
||||
</Text>
|
||||
{' '}
|
||||
<Text>
|
||||
{numFail} <Text style={styles.failText}>Fail</Text>
|
||||
</Text>
|
||||
{numSkipped > 0 ? (
|
||||
<>
|
||||
{' '}
|
||||
<Text>
|
||||
{numSkipped} <Text style={styles.skippedText}>Skipped</Text>
|
||||
</Text>
|
||||
</>
|
||||
) : null}
|
||||
{numError > 0 ? (
|
||||
<>
|
||||
{' '}
|
||||
<Text>
|
||||
{numError} <Text style={styles.errorText}>Error</Text>
|
||||
</Text>
|
||||
</>
|
||||
) : null}
|
||||
{numPending > 0 ? (
|
||||
<>
|
||||
{' '}
|
||||
<Text>
|
||||
{numPending} <Text style={styles.pendingText}>Pending</Text>
|
||||
</Text>
|
||||
</>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
errorText: {
|
||||
color: 'orange',
|
||||
},
|
||||
failText: {
|
||||
color: 'red',
|
||||
},
|
||||
passText: {
|
||||
color: 'green',
|
||||
},
|
||||
pendingText: {
|
||||
color: 'gray',
|
||||
},
|
||||
skippedText: {
|
||||
color: 'blue',
|
||||
},
|
||||
});
|
||||
+10
-2
@@ -28,7 +28,7 @@ export type PlatformTestAssertionResult =
|
||||
| PassingPlatformTestAssertionResult
|
||||
| FailingPlatformTestAssertionResult;
|
||||
|
||||
export type PlatformTestResultStatus = 'PASS' | 'FAIL' | 'ERROR';
|
||||
export type PlatformTestResultStatus = 'PASS' | 'FAIL' | 'ERROR' | 'SKIPPED';
|
||||
|
||||
export type PlatformTestResult = $ReadOnly<{|
|
||||
name: string,
|
||||
@@ -50,8 +50,16 @@ export type AsyncPlatformTest = $ReadOnly<{|
|
||||
done(): void,
|
||||
|}>;
|
||||
|
||||
export type SyncTestOptions = $ReadOnly<{|
|
||||
skip?: boolean,
|
||||
|}>;
|
||||
|
||||
export type PlatformTestHarness = $ReadOnly<{|
|
||||
test(testcase: PlatformTestCase, name: string): void,
|
||||
test(
|
||||
testcase: PlatformTestCase,
|
||||
name: string,
|
||||
options?: SyncTestOptions,
|
||||
): void,
|
||||
useAsyncTest(description: string, timeout?: number): AsyncPlatformTest,
|
||||
|}>;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import type {
|
||||
PlatformTestCase,
|
||||
PlatformTestAssertionResult,
|
||||
PlatformTestContext,
|
||||
SyncTestOptions,
|
||||
} from './RNTesterPlatformTestTypes';
|
||||
|
||||
type AsyncTestStatus = 'NOT_RAN' | 'COMPLETED' | 'TIMED_OUT';
|
||||
@@ -174,7 +175,23 @@ export default function usePlatformTestHarness(): PlatformTestHarnessHookResult
|
||||
}, []);
|
||||
|
||||
const testFunction: PlatformTestHarness['test'] = useCallback(
|
||||
(testCase: PlatformTestCase, name: string): void => {
|
||||
(
|
||||
testCase: PlatformTestCase,
|
||||
name: string,
|
||||
options?: SyncTestOptions,
|
||||
): void => {
|
||||
const {skip = false} = options ?? {};
|
||||
|
||||
if (skip) {
|
||||
addTestResult({
|
||||
name,
|
||||
status: 'SKIPPED',
|
||||
assertions: [],
|
||||
error: null,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const assertionResults: Array<PlatformTestAssertionResult> = [];
|
||||
|
||||
const baseAssert = (
|
||||
|
||||
+42
-17
@@ -14,6 +14,10 @@ import type {PointerEvent} from 'react-native/Libraries/Types/CoreEventTypes';
|
||||
|
||||
import {useMemo} from 'react';
|
||||
|
||||
// These props are not in the specification but are present in the WPT so we keep them
|
||||
// but marked as skipped so we don't prioritize them
|
||||
const SKIPPED_PROPS = ['fromElement', 'toElement'];
|
||||
|
||||
// Check for conformance to PointerEvent interface
|
||||
// TA: 1.1, 1.2, 1.6, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12, 1.13
|
||||
// Adapted from https://github.com/web-platform-tests/wpt/blob/6c26371ea1c144dd612864a278e88b6ba2f3d883/pointerevents/pointerevent_support.js#L15
|
||||
@@ -95,33 +99,54 @@ export function check_PointerEvent(
|
||||
const name = attr[2];
|
||||
const value = attr[3];
|
||||
|
||||
const skip = SKIPPED_PROPS.includes(name);
|
||||
|
||||
// existence check
|
||||
harness.test(({assert_true}) => {
|
||||
assert_true(
|
||||
name in nativeEvent,
|
||||
name + ' attribute in ' + eventType + ' event',
|
||||
);
|
||||
}, pointerTestName + '.' + name + ' attribute exists');
|
||||
harness.test(
|
||||
({assert_true}) => {
|
||||
assert_true(
|
||||
name in nativeEvent,
|
||||
name + ' attribute in ' + eventType + ' event',
|
||||
);
|
||||
},
|
||||
pointerTestName + '.' + name + ' attribute exists',
|
||||
{skip},
|
||||
);
|
||||
|
||||
// readonly check
|
||||
// TODO
|
||||
|
||||
// type check
|
||||
harness.test(({assert_true}) => {
|
||||
assert_true(
|
||||
harness.test(
|
||||
({assert_true}) => {
|
||||
assert_true(
|
||||
// $FlowFixMe
|
||||
idl_type_check[type](nativeEvent[name]),
|
||||
name + ' attribute of type ' + type,
|
||||
);
|
||||
},
|
||||
pointerTestName +
|
||||
'.' +
|
||||
name +
|
||||
' IDL type ' +
|
||||
type +
|
||||
' (JS type was ' +
|
||||
// $FlowFixMe
|
||||
idl_type_check[type](nativeEvent[name]),
|
||||
name + ' attribute of type ' + type,
|
||||
);
|
||||
// $FlowFixMe
|
||||
}, pointerTestName + '.' + name + ' IDL type ' + type + ' (JS type was ' + typeof nativeEvent[name] + ')');
|
||||
typeof nativeEvent[name] +
|
||||
')',
|
||||
{skip},
|
||||
);
|
||||
|
||||
// value check if defined
|
||||
if (value !== undefined) {
|
||||
harness.test(({assert_equals}) => {
|
||||
// $FlowFixMe
|
||||
assert_equals(nativeEvent[name], value, name + ' attribute value');
|
||||
}, pointerTestName + '.' + name + ' value is ' + String(value) + '.');
|
||||
harness.test(
|
||||
({assert_equals}) => {
|
||||
// $FlowFixMe
|
||||
assert_equals(nativeEvent[name], value, name + ' attribute value');
|
||||
},
|
||||
pointerTestName + '.' + name + ' value is ' + String(value) + '.',
|
||||
{skip},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user