Skip to content

Commit

Permalink
Add detox tests for Switch (facebook#22470)
Browse files Browse the repository at this point in the history
Summary:
Reorganized some of the switch examples to be more testable:

Before:
![simulator screen shot - iphone xs - 2018-12-01 at 02 27 47](https://user-images.githubusercontent.com/249164/49327066-bcc35580-f510-11e8-860d-fc07a574f80c.png)

After:
![simulator screen shot - iphone xs - 2018-12-01 at 02 27 06](https://user-images.githubusercontent.com/249164/49327068-bf25af80-f510-11e8-95c6-7aa4a9095b91.png)

Tests pass!

```
yarn build-ios-e2e && yarn test-ios-e2e
```
<img width="711" alt="screen shot 2018-12-01 at 2 20 33 am" src="https://user-images.githubusercontent.com/249164/49327070-c64cbd80-f510-11e8-8cad-84c3fe42941e.png">

Changelog:
----------
Help reviewers and the release process by writing your own changelog entry. When the change doesn't impact React Native developers, it may be ommitted from the changelog for brevity. See below for an example.

[Internal] [Added] - Detox tests for Switch
Pull Request resolved: facebook#22470

Reviewed By: RSNara

Differential Revision: D13290329

Pulled By: TheSavior

fbshipit-source-id: 91c1b895dd5e1acc4330618e6d3165c7f9215997
  • Loading branch information
elicwhite authored and grabbou committed Dec 17, 2018
1 parent 16faf86 commit ba4bab1
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 15 deletions.
54 changes: 54 additions & 0 deletions RNTester/e2e/__tests__/Button-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* 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.
*
* @emails oncall+react_native
* @format
*/

/* global element, by, expect */

describe('Button', () => {
beforeAll(async () => {
await element(by.id('explorer_search')).replaceText('<Button>');
await element(
by.label('<Button> Simple React Native button component.'),
).tap();
});

afterAll(async () => {
//TODO - remove app state persistency, till then, we must go back to main screen,
await element(by.label('Back')).tap();
});

it('Simple button should be tappable', async () => {
await element(by.label('Press Me')).tap();
await expect(element(by.text('Simple has been pressed!'))).toBeVisible();
await element(by.text('OK')).tap();
});

it('Adjusted color button should be tappable', async () => {
await element(by.label('Press Purple')).tap();
await expect(element(by.text('Purple has been pressed!'))).toBeVisible();
await element(by.text('OK')).tap();
});

it("Two buttons with JustifyContent:'space-between' should be tappable", async () => {
await element(by.label('This looks great!')).tap();
await expect(element(by.text('Left has been pressed!'))).toBeVisible();
await element(by.text('OK')).tap();

await element(by.label('Ok!')).tap();
await expect(element(by.text('Right has been pressed!'))).toBeVisible();
await element(by.text('OK')).tap();
});

it('Disabled button should not interact', async () => {
await element(by.label('I Am Disabled')).tap();
await expect(
element(by.text('Disabled has been pressed!')),
).toBeNotVisible();
});
});
84 changes: 84 additions & 0 deletions RNTester/e2e/__tests__/Switch-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* 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.
*
* @emails oncall+react_native
* @format
*/

/* global element, by, expect */

const jestExpect = require('expect');

describe('Switch', () => {
beforeAll(async () => {
await element(by.id('explorer_search')).replaceText('<Switch>');
await element(by.label('<Switch> Native boolean input')).tap();
});

afterAll(async () => {
await element(by.label('Back')).tap();
});

it('Switch that starts on should switch', async () => {
const testID = 'on-off-initial-off';
const indicatorID = 'on-off-initial-off-indicator';

await expect(element(by.id(testID))).toHaveValue('0');
await expect(element(by.id(indicatorID))).toHaveText('Off');
await element(by.id(testID)).tap();
await expect(element(by.id(testID))).toHaveValue('1');
await expect(element(by.id(indicatorID))).toHaveText('On');
});

it('Switch that starts off should switch', async () => {
const testID = 'on-off-initial-on';
const indicatorID = 'on-off-initial-on-indicator';

await expect(element(by.id(testID))).toHaveValue('1');
await expect(element(by.id(indicatorID))).toHaveText('On');
await element(by.id(testID)).tap();
await expect(element(by.id(testID))).toHaveValue('0');
await expect(element(by.id(indicatorID))).toHaveText('Off');
});

it('disabled switch should not toggle', async () => {
const onTestID = 'disabled-initial-on';
const offTestID = 'disabled-initial-off';
const onIndicatorID = 'disabled-initial-on-indicator';
const offIndicatorID = 'disabled-initial-off-indicator';

await expect(element(by.id(onTestID))).toHaveValue('1');
await expect(element(by.id(onIndicatorID))).toHaveText('On');

try {
await element(by.id(onTestID)).tap();
throw new Error('Does not match');
} catch (err) {
jestExpect(err.message.message).toEqual(
jestExpect.stringContaining(
'Cannot perform action due to constraint(s) failure',
),
);
}
await expect(element(by.id(onTestID))).toHaveValue('1');
await expect(element(by.id(onIndicatorID))).toHaveText('On');

await expect(element(by.id(offTestID))).toHaveValue('0');
await expect(element(by.id(offIndicatorID))).toHaveText('Off');
try {
await element(by.id(offTestID)).tap();
throw new Error('Does not match');
} catch (err) {
jestExpect(err.message.message).toEqual(
jestExpect.stringContaining(
'Cannot perform action due to constraint(s) failure',
),
);
}
await expect(element(by.id(offTestID))).toHaveValue('0');
await expect(element(by.id(offIndicatorID))).toHaveText('Off');
});
});
103 changes: 88 additions & 15 deletions RNTester/js/SwitchExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,37 @@
'use strict';

const React = require('react');
const ReactNative = require('react-native');
const {Switch, Text, View} = ReactNative;
const {Switch, Text, View} = require('react-native');

class BasicSwitchExample extends React.Component<{}, $FlowFixMeState> {
type OnOffIndicatorProps = $ReadOnly<{|on: boolean, testID: string|}>;
function OnOffIndicator({on, testID}: OnOffIndicatorProps) {
return <Text testID={testID}>{on ? 'On' : 'Off'}</Text>;
}

type ExampleRowProps = $ReadOnly<{|children: React.Node|}>;
function ExampleRow({children}: ExampleRowProps) {
return (
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 10,
}}>
{children}
</View>
);
}

type SimpleSwitchExampleState = $ReadOnly<{|
trueSwitchIsOn: boolean,
falseSwitchIsOn: boolean,
|}>;

class BasicSwitchExample extends React.Component<
{||},
SimpleSwitchExampleState,
> {
state = {
trueSwitchIsOn: true,
falseSwitchIsOn: false,
Expand All @@ -23,26 +50,72 @@ class BasicSwitchExample extends React.Component<{}, $FlowFixMeState> {
render() {
return (
<View>
<Switch
onValueChange={value => this.setState({falseSwitchIsOn: value})}
style={{marginBottom: 10}}
value={this.state.falseSwitchIsOn}
/>
<Switch
onValueChange={value => this.setState({trueSwitchIsOn: value})}
value={this.state.trueSwitchIsOn}
/>
<ExampleRow>
<Switch
testID="on-off-initial-off"
onValueChange={value => this.setState({falseSwitchIsOn: value})}
value={this.state.falseSwitchIsOn}
/>
<OnOffIndicator
on={this.state.falseSwitchIsOn}
testID="on-off-initial-off-indicator"
/>
</ExampleRow>
<ExampleRow>
<Switch
testID="on-off-initial-on"
onValueChange={value => this.setState({trueSwitchIsOn: value})}
value={this.state.trueSwitchIsOn}
/>
<OnOffIndicator
on={this.state.trueSwitchIsOn}
testID="on-off-initial-on-indicator"
/>
</ExampleRow>
</View>
);
}
}

class DisabledSwitchExample extends React.Component<{}> {
class DisabledSwitchExample extends React.Component<
{||},
SimpleSwitchExampleState,
> {
state = {
trueSwitchIsOn: true,
falseSwitchIsOn: false,
};

render() {
return (
<View>
<Switch disabled={true} style={{marginBottom: 10}} value={true} />
<Switch disabled={true} value={false} />
<ExampleRow>
<Switch
testID="disabled-initial-off"
disabled={true}
onValueChange={value => this.setState({falseSwitchIsOn: value})}
value={this.state.falseSwitchIsOn}
/>

<OnOffIndicator
on={this.state.falseSwitchIsOn}
testID="disabled-initial-off-indicator"
/>
</ExampleRow>

<ExampleRow>
<Switch
testID="disabled-initial-on"
disabled={true}
onValueChange={value => this.setState({trueSwitchIsOn: value})}
value={this.state.trueSwitchIsOn}
/>

<OnOffIndicator
on={this.state.trueSwitchIsOn}
testID="disabled-initial-on-indicator"
/>
</ExampleRow>
</View>
);
}
Expand Down

0 comments on commit ba4bab1

Please sign in to comment.