Skip to content
New issue

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

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

Already on GitHub? # 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.