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

Basic support for Jest runner #335

Merged
merged 20 commits into from
Oct 17, 2017
Merged

Conversation

Kureev
Copy link
Contributor

@Kureev Kureev commented Oct 11, 2017

With this PR merged in, users will be capable of using Jest test runner without significant problems:

  • Now it is possible to use standard interface to run tests:
    detox test -r jest
    instead of
    jest e2e --setupTestFrameworkScriptFile=./jest/setup/e2e-tests.js --runInBand
  • Documentation reflects new test runner mechanism

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.

<3

"test:e2e:build": "detox build"
}
```

We need the `--runInBand` as detox doesn't support parallelism yet.
Copy link
Member

Choose a reason for hiding this comment

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

Will running without the flag run tests serially?

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 added the flag here so if you use detox test -r jest it is always there

Copy link
Contributor

Choose a reason for hiding this comment

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

What is stopping detox from parallelism?

Copy link
Member

Choose a reason for hiding this comment

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

a few things, mainly controlling multiple simulators. It's in our roadmap, shouldn't be too hard.

@@ -38,6 +38,9 @@ switch (program.runner) {
case 'mocha':
command = `node_modules/.bin/${program.runner} ${testFolder} --opts ${testFolder}/${program.runnerConfig} ${configuration} ${loglevel} ${cleanup} ${reuse} ${debugSynchronization} ${artifactsLocation}`;
break;
case 'jest':
Copy link
Member

Choose a reason for hiding this comment

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

What about passing detox command line args? Will those work?

Copy link
Contributor Author

@Kureev Kureev Oct 11, 2017

Choose a reason for hiding this comment

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

We can think of a way doing this. Although, in this version I wasn't aiming to provide this. If this is mandatory, we can discuss the approach

Sorry, misread your comment. What do you mean by "detox cli args"? Can you make an example?

Copy link
Member

Choose a reason for hiding this comment

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

I think it is, the feature is not 100% usable without it.

Copy link
Member

Choose a reason for hiding this comment

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

detox test --configuration ios.sim.release
detox test --loglevel verbose
detox test --debug-synchronization

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Which flags are important?
In the previous version there were no recommendations regarding flags so kept it out of scope. However, I'm fine adding important flags to make jest support even better 💪 .

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rotemmiz what is the goal?

  • tests can access CLI arguments
    or
  • detox can access CLI arguments

If we talk about the second one, then it already works like this (commander parses arguments before passing them to test runner)

Copy link
Member

Choose a reason for hiding this comment

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

You're right, but we execute a child process and these argument are not being passed into it.
cp.execSync(command, {stdio: 'inherit'});
We probably just need to pass them on...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, now I see. Indeed, we just need to pass arguments to the child process. Then there will be no point in passing all these flags in the command itself

Copy link
Contributor Author

@Kureev Kureev Oct 11, 2017

Choose a reason for hiding this comment

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

Seems like jest doesn't support allow custom CLI parameters. The only approach I see is to use environment vars.

Using ENV vars will imply changes on the mocha part and the way test cases gets parameters overall.

UPD: I can update argparse library and CLI so instead of additional flags it'll create one-time ENV variables. For user it'll be still the same, all mapping will happen under the hood.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nice idea @Kureev, thank you so much for your efforts here 👍

@rotemmiz rotemmiz mentioned this pull request Oct 11, 2017
@DanielMSchmidt
Copy link
Contributor

@rotemmiz just a question, would you add different runner to the test matrix?

@hellogerard
Copy link

hellogerard commented Oct 11, 2017

Totally tangential question, but here goes... Been playing around with detox and jest, and I noticed that if I have two test files (e.g. firstTest.spec.js and secondTest.spec.js), detox will terminate, uninstall, install and launch the app for each file. It does not do this with mocha. Any ideas? Is this just because of the repeated call to detox.init()? If so, where would a good place to put this so that it is only called once?

Edit: Happy to create a separate issue if you want.

@Kureev
Copy link
Contributor Author

Kureev commented Oct 11, 2017

detox will terminate, uninstall, install and launch the app for each file.

@hellogerard I believe it is related to --reuse flag. See detox-test.js source for details

@rotemmiz
Copy link
Member

I didn't use Detox with Jest yet, but from what I could see, there is no way to run a global before across files to create a one time setup (which is how detox.init() should be run), so this is indeed an issue.
reference: jestjs/jest#3832

@rotemmiz
Copy link
Member

@DanielMSchmidt Not sure, the only thing we need to test here are is how the test runner is triggered, so it's pretty easy to test with unit tests.

@hellogerard
Copy link

reference: jestjs/jest#3832

@rotemmiz Thanks for that link. There's a PR that closes that issue. Once it's merged, it looks like it can solve the global setup issue. PR is jestjs/jest#4506

@Kureev
Copy link
Contributor Author

Kureev commented Oct 13, 2017

Quick update on the PR: we discussed the way to go with @rotemmiz so you may expect that I'll push my changes today-tomorrow 😉

@hellogerard
Copy link

hellogerard commented Oct 13, 2017

Hmm. I may have spoke too soon, or I don't understand the jest changes. I tried to use the new global setup by doing the following:

  1. Created two test files (e.g. first.spec.js and second.spec.js).

  2. Created a jest-environment-detox.js file:

    require("babel-polyfill");
    
    const NodeEnvironment = require('jest-environment-node');
    
    const detox = require('detox');
    const config = require('../package.json').detox;
    
    class DetoxEnvironment extends NodeEnvironment {
      async setup() {
        try {
          await detox.init(config, { launchApp: true });
        } catch (e) {
          console.log('e', e);
        }
        await super.setup()
      }
    
      async teardown() {
        try {
          await detox.cleanup();
        } catch (e) {
          console.log('e', e);
        }
        await super.teardown()
      }
    }
    
    module.exports = DetoxEnvironment;
  3. Specifying the test environment by passing --testEnvironment="./e2e/jest-environment-detox" to the jest command (full command: jest e2e --runInBand --forceExit --testEnvironment="./e2e/jest-environment-detox")

But no dice. Not only is it running detox.init for each test file, it's not even loading right (i.e. getting device is not defined). Am I doing this right? 😕

EDIT: Forgot to mention I did in fact install jest 21.3.0-beta.2.

@Kureev
Copy link
Contributor Author

Kureev commented Oct 14, 2017

Hi @rotemmiz!

It seems like I have all my unit tests passing locally, but got some issues on CI 🤔 . Can you help me to figure why?

@rotemmiz
Copy link
Member

Seems like some of the params passed to mocha have changed, try running scripts/ci.sh and see if it passes locally

@Kureev
Copy link
Contributor Author

Kureev commented Oct 14, 2017

@rotemmiz seems that after the last fix CI dies due to timeout 😐 . Should I increase it a little bit?

@rotemmiz
Copy link
Member

I have a feeling that something has changed in Travis. We’ll need to debug it, and add better visibility to the build log.

Does everything work locally?

@Kureev
Copy link
Contributor Author

Kureev commented Oct 14, 2017

Does everything work locally?

I have the same problem with timeout on the local machine, but I'll try to extend it (locally) and let you know if it actually works.

@Kureev
Copy link
Contributor Author

Kureev commented Oct 14, 2017

Ok, it gets stuck at

detox verb 3: /usr/bin/xcrun simctl terminate 33E49BFA-ED99-4ACD-A865-5E18863556B7 org.reactjs.native.example.example
detox info 3: Terminating org.reactjs.native.example.example...
detox info 3: org.reactjs.native.example.example terminated
detox verb 4: /bin/cat /dev/null >$HOME/Library/Developer/CoreSimulator/Devices/33E49BFA-ED99-4ACD-A865-5E18863556B7/data/tmp/detox.last_launch_app_log.out 2>$HOME/Library/Developer/CoreSimulator/Devices/33E49BFA-ED99-4ACD-A865-5E18863556B7/data/tmp/detox.last_launch_app_log.err && SIMCTL_CHILD_DYLD_INSERT_LIBRARIES="/Users/xamd/Library/Detox/ios/a719a7fd8af96db5fefad3da20b783f61b168620/Detox.framework/Detox" /usr/bin/xcrun simctl launch --stdout=/tmp/detox.last_launch_app_log.out --stderr=/tmp/detox.last_launch_app_log.err 33E49BFA-ED99-4ACD-A865-5E18863556B7 org.reactjs.native.example.example --args -detoxServer ws://localhost:57195 -detoxSessionId adf47c1c-c956-e93c-7640-cf174d884a54
detox info 4: Launching org.reactjs.native.example.example...

Even if I run my emulator manually, still the same issue... No idea how to debug it. Any suggestions?

UPD: Got an error after timeout

The request was denied by service delegate (SBMainWorkspace) for reason: NotFound ("Application "org.reactjs.native.example.example" is unknown to FrontBoard").

Not sure if it is anyhow related to my patch though 🤔

@rotemmiz
Copy link
Member

I’m not near a computer to verify that, but I think that —args is misplaced (check the last command vs Detox 5.8.2)

@Kureev
Copy link
Contributor Author

Kureev commented Oct 14, 2017

I found an issue in my local setup: seems for some reason my emulator that was used by tests got stuck (no idea, really). After resetting all the settings, everything worked. Will report once I finish all tests locally. 🤞

@Kureev
Copy link
Contributor Author

Kureev commented Oct 14, 2017

I can confirm that all tests (including e2e) are green.

cc @rotemmiz

@rotemmiz
Copy link
Member

Rerunning your build

@rotemmiz
Copy link
Member

I want to add a very important request to this feature: since users choose and setup their test runner probably stick with it for more than an hour, it is important to add an option to configure the test runner in the detox config inside package.json (just like we are able configure the test folder), and ditch the test runner selection as a command line argument.

This should be a very small addition.

@Kureev
Copy link
Contributor Author

Kureev commented Oct 14, 2017

Tested locally on both Xcode 8.3.3 and Xcode 9, could not reproduce the timeout we're having in CI. I'll have to check tomorrow.

If there is a way to reload your iOS emulator on Travis, I would do that first. For me it solved exactly the same problem on my local machine.

@Kureev
Copy link
Contributor Author

Kureev commented Oct 15, 2017

Ready for review, @rotemmiz

@rotemmiz
Copy link
Member

@Kureev, some of our users use Detox with mocha (or any other test runner for that matter) independently of detox-cli. The current change breaks their setup since they can not pass arguments anymore.
When we spoke, I encouraged you use argv and merge them with env vars if needed.
The fact that Jest doesn't support argv doesn't need to enforce other test runners to work with env vars.

@Kureev
Copy link
Contributor Author

Kureev commented Oct 16, 2017

The current change breaks their setup since they can not pass arguments anymore.
When we spoke, I encouraged you use argv and merge them with env vars if needed.
The fact that Jest doesn't support argv doesn't need to enforce other test runners to work with env vars.

Not sure I follow. All arguments are respected 🤔

@rotemmiz
Copy link
Member

Detox core now only supports env vars, not argv. Try running
node_modules/.bin/mocha e2e --opts e2e/mocha.opts --configuration ios.sim.release --loglevel verbose
It will not work.

@Kureev
Copy link
Contributor Author

Kureev commented Oct 16, 2017

Detox core now only supports env vars, not argv. Try running
node_modules/.bin/mocha e2e --opts e2e/mocha.opts --configuration ios.sim.release --loglevel verbose
It will not work.

Sure, but this is not about Detox either. Detox should be run only by detox-cli and detox test command, isn't it correct?

@rotemmiz
Copy link
Member

rotemmiz commented Oct 16, 2017

I don't agree, Detox is test runner independent, and we want to keep it that way.
What if people are using AVAJS now? They have no way of using detox-cli, and we're changing their API under their feet just to add support for other test runner in our CLI tool...
That will not be responsible of us.

In any case, using argv (where possible) is a better and responsible solution, it removes any possibility of environment var leaks.

@Kureev
Copy link
Contributor Author

Kureev commented Oct 16, 2017

What if people are using AVAJS now?

I expect it to be not supported (yet). Otherwise I would expect an article in docs and/or other guidelines' describing how to setup Detox with your-faviourite-tool.

In any case, using argv (where possible) is a better and responsible solution, it removes any possibility of environment var leaks.

I'm fine changing code to support argv on argsparse level, but the part about env var leaks is still not clear to me.

@Kureev
Copy link
Contributor Author

Kureev commented Oct 16, 2017

Should be good now. First we look for the flag in argv and if it isn't there (we use Jest), it falls back to env variable

@@ -975,7 +975,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEAD_CODE_STRIPPING = NO;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = J966JLDEF9;
INFOPLIST_FILE = example/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
Copy link
Member

Choose a reason for hiding this comment

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

Was that added in purpose?

@Kureev
Copy link
Contributor Author

Kureev commented Oct 17, 2017

I reset example.xcodeproj (sorry, committed this change by mistake. I was running this code on my emulator by hand, so had to sign it with certificate ¯\_(ツ)_/¯) + it seems that tests are green again!

@Kureev
Copy link
Contributor Author

Kureev commented Oct 17, 2017

The last CI run was flaky 😒 I changed nothing (okok, I removed my cert pub hash from xcodeproj), but have failed specs. Can you please try to re-run this and let me know if there is anything else you would like me to take care of?

loglevel: program.loglevel,
cleanup: program.cleanup,
reuse: program.reuse,
debugSynchronization: program.debugSynchronization ? 3000 : '',
Copy link
Member

Choose a reason for hiding this comment

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

@Kureev , wouldn't this override every number value with 3000 ?

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 @rotemmiz! Nice catch, fixed! 😉

@rotemmiz rotemmiz merged commit 2647b68 into wix:master Oct 17, 2017
@rotemmiz
Copy link
Member

🎉 !!!
Thanks @Kureev !!

@xfumihiro
Copy link

@hellogerard Jest's TestEnvironment is sandboxed (see this)
Here's the PR for Global setup/teardown

@Kureev Kureev deleted the feature/support-jest-runner branch October 18, 2017 07:04
@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.

6 participants