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

Android: Move expect.js to generated code #746

Merged
merged 3 commits into from
Dec 11, 2018

Conversation

DanielMSchmidt
Copy link
Contributor

Closes #726

@DanielMSchmidt DanielMSchmidt requested a review from rotemmiz as a code owner May 19, 2018 19:04
@rotemmiz
Copy link
Member

getting multiple errors in CI

m should be an instance of Matcher, got "[object Object]", it appears that it has a wrong class name: "Object"
  1. maybe add a toString to that object
  2. unit tests are failing...

@DanielMSchmidt
Copy link
Contributor Author

DanielMSchmidt commented May 20, 2018

Will check that out 👍 worked on my machine TM

@DanielMSchmidt DanielMSchmidt changed the title Move expect.js to generated code [WIP] Move expect.js to generated code May 22, 2018
@DanielMSchmidt DanielMSchmidt force-pushed the danielmschmidt/move-expect-to-generated-code branch 2 times, most recently from 8fba90e to 32f10ed Compare May 29, 2018 17:35
@DanielMSchmidt DanielMSchmidt changed the title [WIP] Move expect.js to generated code Move expect.js to generated code May 30, 2018
@DanielMSchmidt DanielMSchmidt changed the title Move expect.js to generated code [WIP] Move expect.js to generated code Jun 3, 2018
@DanielMSchmidt DanielMSchmidt force-pushed the danielmschmidt/move-expect-to-generated-code branch 3 times, most recently from ff07b22 to e84901e Compare June 10, 2018 21:20
@DanielMSchmidt DanielMSchmidt changed the title [WIP] Move expect.js to generated code Move expect.js to generated code Jun 10, 2018
@DanielMSchmidt DanielMSchmidt force-pushed the danielmschmidt/move-expect-to-generated-code branch 3 times, most recently from 9d1a013 to b89e24f Compare July 12, 2018 20:34
@DanielMSchmidt DanielMSchmidt force-pushed the danielmschmidt/move-expect-to-generated-code branch from b89e24f to 41f4724 Compare July 29, 2018 13:30
@noomorph
Copy link
Collaborator

E2E tests don't pass on Android, almost everything fails with the same error:

  ● Async and Callbacks › should handle async await

    Error: Unhandled arg typeViewInteraction

      71 |     // when this test run fails, we want a stack trace from up here where the
      72 |     // $callee is still available, and not inside the catch block where it isn't
    > 73 |     const potentialError = new Error()
      74 | 
      75 |     try {
      76 |       await this.sendAction(new actions.Invoke(invocation));
      
      at Client.execute (../../src/client/Client.js:73:28)
      at InvocationManager.execute (../../src/invoke.js:11:33)
      at MatcherAssertionInteraction.execute (../../src/android/expect.js:112:29)
      at ExpectElement.toBeVisible (../../src/android/expect.js:244:87)
      at Object.it (10.async-and-callbacks.test.js:17:47)

@DanielMSchmidt , could you take a look please? Try out locally and report what you're getting.
Thanks in advance!

@noomorph
Copy link
Collaborator

noomorph commented Jul 29, 2018

And I confirm that still, I can see the console.error stuff @rotemmiz reported above:

  console.error ../src/android/espressoapi/DetoxAssertion.js:21
    m should be an instance of Matcher, got "[object Object]", it appears that it has a wrong class name: "Object"

It was printed 3-4 times during the test run, is it okay?

@noomorph noomorph self-requested a review July 29, 2018 14:26
@DanielMSchmidt
Copy link
Contributor Author

@noomorph What @rotemmiz saw was an error being thrown, we now have the console.errors, because I could not find the root cause of the check going wrong

@DanielMSchmidt
Copy link
Contributor Author

@noomorph Just checked to be sure and the E2E tests are green and fine 👍

@DanielMSchmidt DanielMSchmidt force-pushed the danielmschmidt/move-expect-to-generated-code branch from 41f4724 to 9db4bc7 Compare August 8, 2018 20:54
@DanielMSchmidt
Copy link
Contributor Author

@noomorph I added the logger to the generated code, please take a look and merge at will 👍

Copy link
Collaborator

@noomorph noomorph left a comment

Choose a reason for hiding this comment

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

@DanielMSchmidt, thanks much! In regards to the codebase, it looks mostly fine except for a few minutiae I listed in the review.

@@ -2,6 +2,11 @@ const fs = require('fs');
const remove = require('remove');
const androidGenerator = require('../adapters/android');

const mockErrorLog = jest.fn();
jest.mock("../../detox/src/utils/logger", () => ({
Copy link
Collaborator

Choose a reason for hiding this comment

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

No need to sophisticate an already sophisticated thing. The logger has already a mocked version __mocks__/logger.js, so you can just use it as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed my own mock and used the one defined in __mocks__/logger.js Unfortunately we have two separate jest installations/contexts, this means I need to do a bit of glue code, but no biggie. I wonder what might happen if we would make more use of a central jest installation with multiple configs with the jest multi-project runners

Might give it a try if I have some spare time 🤔

expect(() => {
ExampleClass.matcherForAnd('I am a string', 'I am one too');
}).not.toThrow();


expect(spy).toHaveBeenCalled();
spy.mockRestore();
expect(mockErrorLog).toHaveBeenCalled();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Correspondingly, you can use expect(logger.error).toHaveBeenCalledWith(expect.any(String))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤷‍♂️ I don't really see a point in having the expect.any(String), but yeah it might sometime in the future catch something, so I'll add it :)

class AnotherClass {}
const x = new AnotherClass();

expect(() => {
ExampleClass.matcherForAnd(x, x);
}).not.toThrow();

expect(spy).toHaveBeenCalled();
spy.mockRestore();
expect(mockErrorLog).toHaveBeenCalled();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Correspondingly, you can use expect(logger.error).toHaveBeenCalledWith(expect.any(String))

const outputPath = pathFragments.join("/")
const absoluteUtilsPath = path.resolve('../detox/src/utils');
const relativeUtilsPath = path.relative(outputPath, absoluteUtilsPath);
const logImport = `const log = require('${relativeUtilsPath}/logger');`;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Change to const log = require('${relativeUtilsPath}/logger').child({ __filename });, so we can track from which files the log messages come.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, could you extract this logic to a separate function, similar to a function createTypeCheck(...) above? I see that generator function looks already loong enough, why make it even bigger? :-)

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, no problem 👍 I think there are some parts I would like to slim down a bit and structure better, will go on with this soonish. My first goal was to get it working,so that I can see every edge case I ran into and make a better layer of abstraction later on ;)

@DanielMSchmidt DanielMSchmidt force-pushed the danielmschmidt/move-expect-to-generated-code branch from ac3b7bf to 94adbd3 Compare August 11, 2018 14:28
@DanielMSchmidt
Copy link
Contributor Author

@noomorph Could you take another look 🙏

@noomorph
Copy link
Collaborator

Looks good the way it is already. If builds pass, more or less, we can try to merge.

P.S. Out of curiosity, why do you do log.error. mockRestore manually?

@DanielMSchmidt
Copy link
Contributor Author

@noomorph are the reset by default?

@DanielMSchmidt
Copy link
Contributor Author

@noomorph Fixed that (the is defined check had a bug so it didn't occur previously, but that is fixed now) and the tests run through 👍

@@ -40,6 +65,24 @@ class ViewActions {
};
}

static click(rollbackAction) {
if (!rollbackAction) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

@DanielMSchmidt , I see unit test failing on this (src/android/expect.js). Is this a reason why you hesitated to add isThruthy check?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will take another look at the unit tests 👍 No, I hesitated because I don't see so much value 🤷‍♂️

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I should have hesitated because of this. The problem is it is optional and not required and we have no way to check if an argument is required or not. So all checks we do should test if the thing that is passed is what it promises to be if something is passed. If null is passed we won't be able to guard us on this side of the fence. I will do a quick research if there is any hypothetical way for us to know if sth is optional and I will let you know.

Copy link
Collaborator

@noomorph noomorph left a comment

Choose a reason for hiding this comment

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

Unit tests are failing, we cannot merge.

@DanielMSchmidt
Copy link
Contributor Author

@noomorph Unit should be fixed now, got weird android simulator issues locally, let
s see what the CI says 😇

@noomorph
Copy link
Collaborator

noomorph commented Sep 8, 2018

Daniel, looks like it is still broken on Android. At least that's what CI tells.

@DanielMSchmidt
Copy link
Contributor Author

Will take a look 🙈

@DanielMSchmidt
Copy link
Contributor Author

@noomorph Could not reproduce, ran it three times on android and one time on iOS and everything went fine.

@DanielMSchmidt DanielMSchmidt force-pushed the danielmschmidt/move-expect-to-generated-code branch from 9cb6bc6 to d9e9d00 Compare September 8, 2018 12:38
@DanielMSchmidt DanielMSchmidt force-pushed the danielmschmidt/move-expect-to-generated-code branch from d9e9d00 to fa808bb Compare October 6, 2018 19:09
@rotemmiz rotemmiz changed the title Move expect.js to generated code [WIP] Move expect.js to generated code Oct 21, 2018
@DanielMSchmidt DanielMSchmidt force-pushed the danielmschmidt/move-expect-to-generated-code branch from b9958f0 to 2f52327 Compare November 21, 2018 16:04
@DanielMSchmidt
Copy link
Contributor Author

So, this branch is now up to date 🎉 Locally it worked (before the massive rebasing I just did), so let's see what CI says 👍

@rotemmiz
Copy link
Member

Looks like the branch is not on par with master, there was an artifacts snapshot test we disabled but still runs here, can you make sure to merge current master to this branch?

@DanielMSchmidt
Copy link
Contributor Author

@rotemmiz That's strange, I rebased it from master before I pushed, so I am a bit confused. I can't see where I enabled it looking through the diff.

@DanielMSchmidt
Copy link
Contributor Author

I tried to see if sth is different on the JSON part send to the WS for the failing test, but they are identical (besides message id). So I think your hint into enabling a disabled functionality seems to be right.

@DanielMSchmidt DanielMSchmidt changed the title [WIP] Move expect.js to generated code Move expect.js to generated code Nov 21, 2018
@DanielMSchmidt DanielMSchmidt force-pushed the danielmschmidt/move-expect-to-generated-code branch 2 times, most recently from 2cce220 to f072bf2 Compare November 25, 2018 08:33
@DanielMSchmidt
Copy link
Contributor Author

This is fixed and green on CI. @noomorph and @rotemmiz please review 😇

Copy link
Member

@rotemmiz rotemmiz left a comment

Choose a reason for hiding this comment

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

I'm having trouble understanding the overload functions generation. Can you explain about that a bit?

value: metaState
}]
};
function pressKeyCode1(keyCode) {
Copy link
Member

Choose a reason for hiding this comment

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

What happened here?
I guess there's problem with Java overloads, did you handle it somewhere else in a different way?
Seems like the original code just has metaState=0 as default.
https://android.googlesource.com/platform/frameworks/testing/+/79693ed/uiautomator/library/src/com/android/uiautomator/core/UiDevice.java#285

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The easiest way to handle overloading is to just check for the number of arguments. There are for sure better, more reliable ways, but this was the fastest. (I have checks in place that make sure we get some console output if we mess up here)

};
}

if (arguments.length === 1) {
Copy link
Member

Choose a reason for hiding this comment

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

is this generated code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes

args: []
};
}

static click() {
function click0() {
Copy link
Member

Choose a reason for hiding this comment

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

Again here, why are there two clicks?
I see only one in UIDevice API

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are two because the method is overloaded.

@@ -0,0 +1,11 @@
/**
Copy link
Member

Choose a reason for hiding this comment

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

We can probably throw this away, as this class is empty. Everything is in EarlGreyImpl

"../detox/src/ios/earlgreyapi/GREYConfiguration.js",
"../detox/ios/EarlGrey/EarlGrey/Core/EarlGreyImpl.h":
"../detox/src/ios/earlgreyapi/EarlGreyImpl.js"
'../detox/ios/EarlGrey/EarlGrey/Action/GREYActions.h': '../detox/src/ios/earlgreyapi/GREYActions.js',
Copy link
Member

Choose a reason for hiding this comment

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

better!

Daniel Schmidt added 3 commits December 11, 2018 13:41
Previously we had manually changed code in the generated sections.
@DanielMSchmidt DanielMSchmidt force-pushed the danielmschmidt/move-expect-to-generated-code branch from f072bf2 to 7cd7704 Compare December 11, 2018 12:42
@rotemmiz rotemmiz merged commit 491bb52 into master Dec 11, 2018
@rotemmiz rotemmiz changed the title Move expect.js to generated code Android: Move expect.js to generated code Dec 11, 2018
@lock lock bot locked as resolved and limited conversation to collaborators Dec 14, 2018
@noomorph noomorph deleted the danielmschmidt/move-expect-to-generated-code branch April 18, 2019 06:12
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants