Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Device Orientation Manipulation #133

Merged
merged 9 commits into from
May 25, 2017
18 changes: 18 additions & 0 deletions detox/src/devices/Simulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const IosNoneDevice = require('./IosNoneDevice');
const FBsimctl = require('./Fbsimctl');
const configuration = require('../configuration');
const argparse = require('../utils/argparse');
const invoke = require('../invoke');

class Simulator extends IosNoneDevice {

Expand Down Expand Up @@ -97,6 +98,23 @@ class Simulator extends IosNoneDevice {
async shutdown() {
await this._fbsimctl.shutdown(this._simulatorUdid);
}

async setOrientation(orientation) {
// keys are possible orientations
const orientationMapping = {
landscape: 3, // top at left side landscape
portrait: 1 // non-reversed portrait
};
if (!Object.keys(orientationMapping).includes(orientation)) {
throw new Error(`setOrientation failed: provided orientation ${orientation} is not part of supported orientations: ${Object.keys(orientationMapping)}`)
}

const call = invoke.call(invoke.EarlGrey.instance,
'rotateDeviceToOrientation:errorOrNil:',
invoke.IOS.NSInteger(orientationMapping[orientation])
);
await new invoke.InvocationManager(this.client).execute(call);
}
}

module.exports = Simulator;
33 changes: 33 additions & 0 deletions detox/src/devices/Simulator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,39 @@ describe('Simulator', () => {
await simulator.openURL(url);
expect(simulator._fbsimctl.open).toHaveBeenCalledWith(simulator._simulatorUdid, url);
});

it(`setOrientation() should throw an error if give wrong input `, async() => {
expect.assertions(1);
simulator = validSimulator();

try {
await simulator.setOrientation('UpsideDown');
} catch(e) {
expect(e.message).toMatch('setOrientation failed: provided orientation UpsideDown is not part of supported orientations: landscape,portrait');
}
});

it(`setOrientation() should set the orientation to portrait`, async() => {
simulator = validSimulator();

await simulator.setOrientation('portrait');
expect(client.execute).toHaveBeenCalled();
const call = client.execute.mock.calls[client.execute.mock.calls.length - 1][0]();
expect(call.target.type).toBe('EarlGrey');
expect(call.method).toBe('rotateDeviceToOrientation:errorOrNil:');
expect(call.args[0].value).toBe(1);
});

it(`setOrientation() should set the orientation to landscape`, async() => {
simulator = validSimulator();

await simulator.setOrientation('landscape');
expect(client.execute).toHaveBeenCalled();
const call = client.execute.mock.calls[client.execute.mock.calls.length - 1][0]();
expect(call.target.type).toBe('EarlGrey');
expect(call.method).toBe('rotateDeviceToOrientation:errorOrNil:');
expect(call.args[0].value).toBe(3);
});
});

const notification = {
Expand Down
24 changes: 24 additions & 0 deletions detox/test/e2e/f-simulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,28 @@ describe('Simulator', () => {
await element(by.label('Say Hello')).tap();
await expect(element(by.label('Hello!!!'))).toBeVisible();
});

describe('device orientation', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome stuff!

beforeEach(async() => {
await device.reloadReactNative();
await element(by.label('Orientation')).tap();

// Check if the element whichs input we will test actually exists
await expect(element(by.id('currentOrientation'))).toExist();
});

it('OrientationLandscape', async () => {
await device.setOrientation('landscape');

await expect(element(by.id('currentOrientation'))).toHaveText('Landscape');
});

it('OrientationPortrait', async() => {
// As default is portrait we need to set it otherwise
await device.setOrientation('landscape');
await device.setOrientation('portrait');

await expect(element(by.id('currentOrientation'))).toHaveText('Portrait');
});
});
});
1 change: 1 addition & 0 deletions detox/test/index.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class example extends Component {
{this.renderScreenButton('Stress', Screens.StressScreen)}
{this.renderScreenButton('Switch Root', Screens.SwitchRootScreen)}
{this.renderScreenButton('Timeouts', Screens.TimeoutsScreen)}
{this.renderScreenButton('Orientation', Screens.Orientation)}
</View>
);
}
Expand Down
33 changes: 33 additions & 0 deletions detox/test/src/Screens/Orientation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React, { Component } from 'react';
import {
Text,
View,
TouchableOpacity
} from 'react-native';

export default class Orientation extends Component {

constructor(props) {
super(props);
this.state = {
horizontal: false
};
console.log('Orientation react component constructed (console.log test)');
}

detectHorizontal({nativeEvent: {layout: {width, height,x,y}}}) {
this.setState({
horizontal: width > height
});
}

render() {
return (
<View onLayout={this.detectHorizontal.bind(this)} style={{flex: 1, paddingTop: 20, justifyContent: 'flex-start', alignItems: 'center'}}>
<Text testID="currentOrientation" style={{fontSize: 25, marginTop: 50}}>
{this.state.horizontal ? 'Landscape' : 'Portrait'}
</Text>
</View>
);
}
}
4 changes: 3 additions & 1 deletion detox/test/src/Screens/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import WaitForScreen from './WaitForScreen';
import StressScreen from './StressScreen';
import SwitchRootScreen from './SwitchRootScreen';
import TimeoutsScreen from './TimeoutsScreen';
import Orientation from './Orientation';

export {
SanityScreen,
Expand All @@ -15,5 +16,6 @@ export {
WaitForScreen,
StressScreen,
SwitchRootScreen,
TimeoutsScreen
TimeoutsScreen,
Orientation
};
4 changes: 4 additions & 0 deletions docs/APIRef.DeviceObjectAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@ Uninstall the app defined in the current [`configuration`](APIRef.Configuration.


### `device.sendUserNotification(params)`

### `device.setOrientation(orientation)`
Takes `"portrait"` or `"landscape"` and rotates the device to the given orientation.
Currently only available in the iOS Simulator.