diff --git a/RNTester/e2e/__tests__/Alert-test.js b/RNTester/e2e/__tests__/Alert-test.js new file mode 100644 index 00000000000000..208857b213bfb0 --- /dev/null +++ b/RNTester/e2e/__tests__/Alert-test.js @@ -0,0 +1,50 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +/* global device, element, by, expect, waitFor */ +const {openExampleWithTitle} = require('../e2e-helpers'); + +describe('Alert', () => { + beforeAll(async () => { + await element(by.id('explorer_search')).replaceText('Alert'); + await element(by.text('Alerts')).tap(); + }); + + afterAll(async () => { + await element(by.label('Back')).tap(); + }); + + it('should show alert dialog with message and default button', async () => { + const alertMessage = 'An external USB drive has been detected!'; + + await openExampleWithTitle('Alert with default Button'); + await element(by.id('alert-with-default-button')).tap(); + await expect(element(by.text(alertMessage))).toBeVisible(); + await element(by.text('OK')).tap(); + }); + + it('should show alert dialog with three buttons', async () => { + const alertMessage = 'Do you want to save your changes?'; + + await openExampleWithTitle('Alert with three Buttons'); + await element(by.id('alert-with-three-buttons')).tap(); + await expect(element(by.text(alertMessage))).toBeVisible(); + await expect(element(by.text('Cancel'))).toBeVisible(); + await expect(element(by.text('No'))).toBeVisible(); + await expect(element(by.text('Yes'))).toBeVisible(); + await element(by.text('Yes')).tap(); + }); + + it('should successfully call the callback on button press', async () => { + await openExampleWithTitle('Alert with three Buttons'); + await element(by.id('alert-with-three-buttons')).tap(); + await element(by.text('Cancel')).tap(); + await expect(element(by.text('Log: Cancel Pressed!'))).toBeVisible(); + }); +}); diff --git a/RNTester/js/examples/Alert/AlertExample.js b/RNTester/js/examples/Alert/AlertExample.js index 4e362a525f91f9..2383352117cab4 100644 --- a/RNTester/js/examples/Alert/AlertExample.js +++ b/RNTester/js/examples/Alert/AlertExample.js @@ -9,137 +9,188 @@ 'use strict'; -const React = require('react'); -const { - Alert, - StyleSheet, - Text, - TouchableHighlight, - View, -} = require('react-native'); - -const RNTesterBlock = require('../../components/RNTesterBlock'); - -// corporate ipsum > lorem ipsum -const alertMessage = - 'Credibly reintermediate next-generation potentialities after goal-oriented ' + - 'catalysts for change. Dynamically revolutionize.'; +import React, {useState} from 'react'; +import {Alert, StyleSheet, Text, TouchableHighlight, View} from 'react-native'; + +// Shows log on the screen +const Log = ({message}) => + message ? ( + + + Log: {message} + + + ) : null; /** * Simple alert examples. */ -type Props = $ReadOnly<{||}>; - -class SimpleAlertExampleBlock extends React.Component { - render() { - return ( - - Alert.alert('Alert Title', alertMessage)}> - - Alert with message and default button - - - - Alert.alert('Alert Title', alertMessage, [ - {text: 'OK', onPress: () => console.log('OK Pressed!')}, - ]) - }> - - Alert with one button - - - - Alert.alert('Alert Title', alertMessage, [ - {text: 'Cancel', onPress: () => console.log('Cancel Pressed!')}, - {text: 'OK', onPress: () => console.log('OK Pressed!')}, - ]) - }> - - Alert with two buttons - - - - Alert.alert('Alert Title', null, [ - {text: 'Foo', onPress: () => console.log('Foo Pressed!')}, - {text: 'Bar', onPress: () => console.log('Bar Pressed!')}, - {text: 'Baz', onPress: () => console.log('Baz Pressed!')}, - ]) - }> - - Alert with three buttons - - - - Alert.alert( - 'Foo Title', - alertMessage, - '..............'.split('').map((dot, index) => ({ - text: 'Button ' + index, - onPress: () => console.log('Pressed ' + index), - })), - ) - }> - - Alert with too many buttons - - - - Alert.alert( - 'Alert Title', - null, - [{text: 'OK', onPress: () => console.log('OK Pressed!')}], - { - cancelable: false, - }, - ) - }> - - Alert that cannot be dismissed - - - - Alert.alert('', alertMessage, [ - {text: 'OK', onPress: () => console.log('OK Pressed!')}, - ]) - }> - - Alert without title - - - - ); - } -} - -class AlertExample extends React.Component { - static title = 'Alert'; - - static description = - 'Alerts display a concise and informative message ' + - 'and prompt the user to make a decision.'; - - render() { - return ( - - - - ); - } -} + +const AlertWithDefaultButton = () => { + const alertMessage = 'An external USB drive has been detected!'; + + return ( + + Alert.alert('Alert', alertMessage)}> + + Tap to view alert + + + + ); +}; + +const AlertWithTwoButtons = () => { + const [message, setMessage] = useState(''); + + const alertMessage = 'Your subscription has expired!'; + + return ( + + + Alert.alert('Action Required!', alertMessage, [ + {text: 'Ignore', onPress: () => setMessage('Ignore Pressed!')}, + {text: 'Renew', onPress: () => setMessage('Renew Pressed!')}, + ]) + }> + + Tap to view alert + + + + + ); +}; + +const AlertWithThreeButtons = () => { + const [message, setMessage] = useState(''); + + const alertMessage = 'Do you want to save your changes?'; + + return ( + + + Alert.alert('Unsaved Changes!', alertMessage, [ + {text: 'Cancel', onPress: () => setMessage('Cancel Pressed!')}, + {text: 'No', onPress: () => setMessage('No Pressed!')}, + {text: 'Yes', onPress: () => setMessage('Yes Pressed!')}, + ]) + }> + + Tap to view alert + + + + + ); +}; + +const AlertWithManyButtons = () => { + const [message, setMessage] = useState(''); + + const alertMessage = + 'Credibly reintermediate next-generation potentialities after goal-oriented ' + + 'catalysts for change. Dynamically revolutionize.'; + + return ( + + + Alert.alert( + 'Foo Title', + alertMessage, + '..............'.split('').map((dot, index) => ({ + text: 'Button ' + index, + onPress: () => setMessage(`Button ${index} Pressed!`), + })), + ) + }> + + Tap to view alert + + + + + ); +}; + +const AlertWithCancelableTrue = () => { + const [message, setMessage] = useState(''); + + const alertMessage = 'Tapping outside this dialog will dismiss this alert.'; + + return ( + + + Alert.alert( + 'Alert Title', + alertMessage, + [{text: 'OK', onPress: () => setMessage('OK Pressed!')}], + { + cancelable: true, + onDismiss: () => + setMessage( + 'This alert was dismissed by tapping outside of the alert dialog.', + ), + }, + ) + }> + + Tap to view alert + + + + + ); +}; + +const AlertWithStyles = () => { + const [message, setMessage] = useState(''); + + const alertMessage = 'Look at the button styles!'; + + return ( + + + Alert.alert('Styled Buttons!', alertMessage, [ + { + text: 'Default', + onPress: () => setMessage('Default Pressed!'), + style: 'default', + }, + { + text: 'Cancel', + onPress: () => setMessage('Cancel Pressed!'), + style: 'cancel', + }, + { + text: 'Destructive', + onPress: () => setMessage('Destructive Pressed!'), + style: 'destructive', + }, + ]) + }> + + Tap to view alert + + + + + ); +}; const styles = StyleSheet.create({ wrapper: { @@ -150,9 +201,66 @@ const styles = StyleSheet.create({ backgroundColor: '#eeeeee', padding: 10, }, + logContainer: { + paddingVertical: 8, + paddingHorizontal: 5, + }, + bold: { + fontWeight: 'bold', + }, }); -module.exports = { - AlertExample, - SimpleAlertExampleBlock, -}; +exports.title = 'Alerts'; +exports.description = + 'Alerts display a concise and informative message ' + + 'and prompt the user to make a decision.'; +exports.examples = [ + { + title: 'Alert with default Button', + description: + "It can be used to show some information to user that doesn't require an action.", + render(): React.Node { + return ; + }, + }, + { + title: 'Alert with two Buttons', + description: 'It can be used when an action is required from the user.', + render(): React.Node { + return ; + }, + }, + { + title: 'Alert with three Buttons', + description: 'It can be used when there are three possible actions', + render(): React.Node { + return ; + }, + }, + { + title: 'Alert with many Buttons', + platform: 'ios', + description: 'It can be used when more than three actions are required.', + render(): React.Node { + return ; + }, + }, + { + title: 'Alert with cancelable={true}', + platform: 'android', + description: + 'By passing cancelable={false} prop to alerts on Android, they can be dismissed by tapping outside of the alert box.', + render(): React.Node { + return ; + }, + }, + { + title: 'Alert with styles', + platform: 'ios', + description: + "Alert buttons can be styled. There are three button styles - 'default' | 'cancel' | 'destructive'.", + render(): React.Node { + return ; + }, + }, +]; \ No newline at end of file diff --git a/RNTester/js/examples/Alert/AlertIOSExample.js b/RNTester/js/examples/Alert/AlertIOSExample.js index 18bcaa4655da5a..033c0ab58831a2 100644 --- a/RNTester/js/examples/Alert/AlertIOSExample.js +++ b/RNTester/js/examples/Alert/AlertIOSExample.js @@ -12,7 +12,7 @@ const React = require('react'); -const {SimpleAlertExampleBlock} = require('./AlertExample'); +const {examples: CommonAlertExamples} = require('./AlertExample'); const { StyleSheet, View, @@ -155,12 +155,7 @@ exports.framework = 'React'; exports.title = 'Alert'; exports.description = 'iOS alerts and action sheets'; exports.examples = [ - { - title: 'Alerts', - render(): React.Node { - return ; - }, - }, + ...CommonAlertExamples, { title: 'Prompt Options', render(): React.Element { @@ -201,4 +196,4 @@ exports.examples = [ ); }, }, -]; +]; \ No newline at end of file diff --git a/RNTester/js/utils/RNTesterList.android.js b/RNTester/js/utils/RNTesterList.android.js index 66962af515439d..f2da83458bbd45 100644 --- a/RNTester/js/utils/RNTesterList.android.js +++ b/RNTester/js/utils/RNTesterList.android.js @@ -122,7 +122,7 @@ const APIExamples: Array = [ }, { key: 'AlertExample', - module: require('../examples/Alert/AlertExample').AlertExample, + module: require('../examples/Alert/AlertExample'), }, { key: 'AnimatedExample',