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

Conversation

DanielMSchmidt
Copy link
Contributor

@DanielMSchmidt DanielMSchmidt commented May 20, 2017

This PR adds device orientation change support to the device API (see #131).
Last thing to do is add some description to the docs, at least from my perspective.

@talkol @rotemmiz Can you give me feedback for the implementation? Is there anything I could do better next time? The docs will follow tomorrow or the day after 👍

  • remove extension to MethodInvocation.m
  • use earl grey function directly in setOrientation
  • move JS implementation to Simulator.js
  • write unit tests
  • add docs

@@ -80,6 +80,24 @@ + (id) getValue:(id)value withType:(id)type onError:(void (^)(NSString*))onError
if (![value isKindOfClass:[NSDictionary class]]) return nil;
return [MethodInvocation invoke:value onError:onError];
}
if ([type isEqualToString:@"UIDeviceOrientation"])
Copy link
Member

Choose a reason for hiding this comment

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

The main advantage of the remote invocation mechanism is that we don't need to add any other new call to the protocol

I believe we didn't make the invocation mechanism easily accessible for extension, and this is our fault.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does this mean I could have written invoke.IOS.UIDeviceOrientation('UIDeviceOrientationLandscapeLeft') or what would the JS call need to look like in this case?

@@ -42,6 +43,16 @@ class Device {
await this.client.sendUserNotification(params);
}

async setOrientation(orientation) {
Copy link
Member

Choose a reason for hiding this comment

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

Device.js is platform agnostic, it's a base class (will be the base class for Android devices as well). This is a simulator specific logic, hence needs to be in Simulator.js

Copy link
Member

Choose a reason for hiding this comment

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

I see there are no unit tests here, the build will fail on lack of coverage.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, I will move it to Simulator.js and add some unit tests

@@ -42,6 +43,16 @@ class Device {
await this.client.sendUserNotification(params);
}

async setOrientation(orientation) {
// orientation is 'landscape' (meaning left side portrait) or 'portrait' (non-reversed)
const call = invoke.call(
Copy link
Member

Choose a reason for hiding this comment

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

you can invoke the EarlGrey functions directly instead

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So I would do

invoke.IOS.EarlGrey(
         'rotateDeviceToOrientation:errorOrNil:',
        invoke.IOS.UIDeviceOrientation(orientation)
);

or how would it have to look like?

Copy link
Member

@rotemmiz rotemmiz May 25, 2017

Choose a reason for hiding this comment

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

The ObjC code looks like this:

[EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft errorOrNil:nil];

JS code pass UIDeviceOrientation which is an enum, so I guess the easiest way is to pass NSInteger with the position of the desired orientation enum.

Looking at UIDevice.h, which holds these enums

typedef NS_ENUM(NSInteger, UIDeviceOrientation) {
    UIDeviceOrientationUnknown,
    UIDeviceOrientationPortrait,            // Device oriented vertically, home button on the bottom
    UIDeviceOrientationPortraitUpsideDown,  // Device oriented vertically, home button on the top
    UIDeviceOrientationLandscapeLeft,       // Device oriented horizontally, home button on the right
    UIDeviceOrientationLandscapeRight,      // Device oriented horizontally, home button on the left
    UIDeviceOrientationFaceUp,              // Device oriented flat, face up
    UIDeviceOrientationFaceDown             // Device oriented flat, face down
} __TVOS_PROHIBITED;

For UIDeviceOrientationPortrait pass pass invoke.IOS.NSInteger(1)
For UIDeviceOrientationLandscapeLeft pass invoke.IOS.NSInteger(3)

I think this should work ...
Of course, for readability, we'd like to keep this enum values in JS as well.

So it would look something like this:

let invocation = invoke.IOS.EarlGrey(
         'rotateDeviceToOrientation:errorOrNil:',
        invoke.IOS.NSInteger(orientationEnum)
await invocationManager.execute(invocation);
);

I hope it'll work :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey, thanks for the insight, got it working without any native extension (yay 🎉 ). Though the call you describe doesn't work, it leads to an object like

{
    type: "EarlGrey",
    value: "rotateDeviceToOrientation:errorOrNil:",
    id: 5
}

This leads to a "target is invalid" error, which, to me, looks a bit like a "bug", right?

Copy link
Member

Choose a reason for hiding this comment

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

I spent try my code, it's reasonable I mistaken.
What is the working syntax then?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I just wanted to state that calling

invoke.IOS.EarlGrey(
         'rotateDeviceToOrientation:errorOrNil:',
        invoke.IOS.NSInteger(orientationEnum)
);

would be the most readable and easiest way, I will try to make it work, the tests will tell me if I did something wrong then ;)

@@ -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!

throw new Error(`setOrientation failed: provided orientation ${orientation} is not part of supported orientations: ${Object.keys(orientationMapping)}`)
}

const call = invoke.EarlGrey.call(
Copy link
Member

Choose a reason for hiding this comment

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

take a look here

this._call = invoke.call(invoke.EarlGrey.instance, 'detox_selectElementWithMatcher:', matcher._call);

https://github.com/wix/detox/blob/master/detox/src/ios/expect.js#L229

This function calls the static methoddetox_selectElementWithMatcher function in EarlGrey

@@ -3,6 +3,18 @@ const instance = {
value: 'instance'
};

function call(method, ...args) {
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need to add a special call function here, we are calling EarlGrey's static methods elsewhere without the need for this code.

invoke.IOS.CGPoint({x: 2, y: 1}))

to actually work with no CGPoint function ever existing

https://github.com/wix/detox/blob/master/detox/src/invoke.test.js#L19

@DanielMSchmidt
Copy link
Contributor Author

@rotemmiz Can you give me final feedback, this PR is done from my side (at least as far as I can tell 👍 )

@rotemmiz rotemmiz merged commit e74ea68 into wix:master May 25, 2017
@rotemmiz rotemmiz changed the title WIP | Device Orientation Manipulation Device Orientation Manipulation May 27, 2017
@wix wix locked and limited conversation to collaborators Jul 23, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants