-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Running on windows support #628
Conversation
Also I didn't touch |
@simonbuchan Thank you for taking care of this <3 👍 |
There's a lot more rough edges I'd like to iron out first, e.g. when using I've got a couple of hacks that could make all the tests pass on windows (all just path separators, AFAICT), but I don't know if that means they actually work right! At least until I've gotten on top of those I'm not sure where a windows CI would help, nor how that would work. You might have noticed I had to ignore the windows branch in exec for coverage to pass, and I'm not sure how that would work cross-platform (collect on all platforms and merge in a final step? Sounds complex!) So far not sure what docs would change? "Windows will probably mostly work" isn't a great line! And I'd like to see some other users experience with this first before promising more. The big difference would probably be whatever happens with Ideally we will be using this cross-platform quite a bit more in the future, and I'll be happy to follow this up with more support on request (though keep in mind I'm in UTC+12:00). |
Talking of CI, actually, I noticed there's a pretty complex |
Let me know if the above fix is OK in theory, it seems to be required for windows |
This is something we'll have to test locally, there's no test in CI that verifies that a second e2e works, or is there....
|
It seems like it does, since it still has 100% coverage? I might be misunderstanding branch coverage. |
I will be reviewing this soon, sorry for the delay. |
is this going to be merged soon? :-) |
detox/src/devices/EmulatorDriver.js
Outdated
await this.emulator.boot(name); | ||
} | ||
|
||
adbDevices = await this.adb.devices(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this being run twice ?
Does the original implementation cause issues with Windows ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, should be inside the if
here - it's refreshing adbDevices
after the requested name is booted. See the comments above as to why this is happening, but roughly: on windows trying to start the emulator the way it currently is being done when it's already running causes issues for some reason.
const path = require('path'); | ||
|
||
program.parse(process.argv); | ||
|
||
if (fs.existsSync(path.join(process.cwd(), 'node_modules/.bin/detox-server'))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
npm and yarn install detox-server at different locations.
it might be either it node_modules
or in node_modules/detox/node_modules
I am not familiar with require.resolve('detox-server/package.json');
trick. Will it cover both cases ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, it's the standard hack to find the location of an NPM package the same way node does, since every NPM package has a package.json
. Remember:
require / require.resolve('foo/bar')
looks upfoo
in node_modules, then addsbar
to that path- without the
.../bar
it would use themain
field, which is likely to be in a nested subdir package.json
always exists.
detox/scripts/postinstall.js
Outdated
@@ -0,0 +1,8 @@ | |||
#!/usr/bin/env node | |||
|
|||
// Javascript for windows support. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More clearly Using JS instead of shell script to avoid breaking on windows
, but I'm happy to remove it!
Sorry for the delay in reviewing, but it is now done :) Unfortunately, we have no capacity to run Detox on Windows in CI, therefore I cannot guarantee this will continue working without breaking. We will need to add a disclaimer in the docs, and rely on the community to report issues and fix them. :( |
If you want to look into CI later, the standard I've seen in open source is https://www.appveyor.com/ |
Looking around, seems like AppVeyor is mostly NuGet packages. Node packages (including typescript, babel and react-native itself) all use https://circleci.com/ |
CI failureHmm, not sure what's up: only one config, so seems like it flaked? CIBlorg, never mind, CircleCI is mac/linux only. Looks like:
Weird. Seems like AppVeyor do have decent-ish node support, even if the docs are old. I could look into setting this up, I think the main thing would be installing the android SDK on windows reliably. TestsNote that the tests do not all pass on windows yet - here's an example, all 4 failures are trivial path things like this:
I'm not sure what you want to do here, some options are:
I do have a Mac Mini for iOS dev now (it's absolutely terrible to work on, but it works 🤷), so I can be more confident I'm not breaking things, I guess. |
Re tests, it sounds reasonable to just use Node's compatibility layer. |
Are you referring to Another, cleaner answer would be to change the tests so they look something like: const inputApkPath = path.join(_dirname, 'build/outputs/apk/debug/app-debug.apk');
const expectedTestApkPath = path.join(_dirname, 'build/outputs/apk/androidTest/debug/app-debug-androidTest.apk'); but this means the actual diffs depend on the repo working directory path. |
Use path module in tests to normalize paths. Use process.platform to test with actual absolute paths on windows.
OK updated tests - should be safe and straightforward changes. Were there specific things you wanted in terms of doc changes? At the moment, all I can think of is something like "windows should probably work, but be aware that Other than that I think this is good to go modulo follow-up reviews. |
While writing some docs noticed I hadn't gotten around to Let me know if these docs are OK, I'm not 100% on the tone or placement. Hopefully that CI failure was just a flake? Not sure how I could have broken it. |
Incidentally, while testing |
We have two flavors for the test app, fromBin and fromSource. The thing is, even if you build from bin, the fact that the settings.gradle includes You can remark it in Tell me if it works. |
Yeah. that seems to work fine, and the tests pass. (It was complaining about a missing |
}); | ||
|
||
it(`should accept relative path for binary`, async () => { | ||
const actualPath = await launchAndTestBinaryPath('relativePath'); | ||
expect(actualPath).toEqual(`${process.cwd()}/abcdef/123`); | ||
expect(actualPath).toEqual(path.join(process.cwd(), 'abcdef/123')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be split to path.join(process.cwd(), 'abcdef', '123')
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Path will normalise separators, and windows in fine with either except for binary paths (where they are ambiguous with switches)
@@ -52,10 +52,18 @@ class EmulatorDriver extends AndroidDriver { | |||
} | |||
|
|||
await this._fixEmulatorConfigIniSkinName(name); | |||
await this.emulator.boot(name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was the issue here ? boot should return a valid device, either it's shutdown or already booted. If it doesn't we may have issue with Emulator.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I now see the comments here.
Not sure how to proceed here. This fix is in bad taste IMO.
So the real issue is creating and removing those emulator log files ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could experiment a bit, I suspect redirecting to different files should fix it, but this was a less user visible change (eg. .gitignore)
Do you not find it logical to only start an emulator if it's not already running?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, gave it a try and it still hangs on startup with no output to the log file even if it's a new file each time.
Killing the first emulator then will hang it, killing it causes the second to start up and detox to continue successfully.
Seems like there's something lower level specific to the android emulator going on, possibly needs to have a separate AVD directory?
docs/More.Roadmap.md
Outdated
@@ -11,6 +11,14 @@ The current API supports addition of multiple platforms, Android is next. This i | |||
### iOS physical device support | |||
Currently detox only supports running on iOS simulators, we plan on adding support for running on devices as well. | |||
|
|||
### Windows support | |||
There is some work done for running detox on Windows, but it's still fairly untested. Please open issues for anything you run into, but be aware of these limitations: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Detox, not detox
docs/More.Roadmap.md
Outdated
- `binaryPath` can be left as a relative path with `/`, or use `\\` if you don't need cross-platform support. | ||
- `build` should not use `./gradlew ...`, but simply `gradlew ...` - you may prefer scripting the build outside of | ||
detox if you want to maintain cross-platform support - or simply have two configurations! | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👌
docs/More.Roadmap.md
Outdated
- Apple doesn't support iOS apps on Windows, obviously, so you're limited to the in-progress Android support. | ||
- `binaryPath` can be left as a relative path with `/`, or use `\\` if you don't need cross-platform support. | ||
- `build` should not use `./gradlew ...`, but simply `gradlew ...` - you may prefer scripting the build outside of | ||
detox if you want to maintain cross-platform support - or simply have two configurations! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is there a line break here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, should be “Detox”.
docs/More.Roadmap.md
Outdated
### Windows support | ||
There is some work done for running Detox on Windows, but it's still fairly untested. Please open issues for anything you run into, but be aware of these limitations: | ||
|
||
- Apple doesn't support iOS apps on Windows, obviously, so you're limited to the in-progress Android support. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let’s please remove the “obviously”.
Gah. 🤦♂️ Thanks for the reviews guys! |
Hah, just looked the jenkins log and saw a big fat crash stack at the end... then noticed it was the app crash test 😅 |
🎉🕊 Thanks so much for all the discussion and feedback! This turned out a lot bigger and gnarlier than I expected at the start, but isn't that always the way! |
Thank you for all the good work! |
Thanks for the great work, hope you stick around. |
Just a few issues I ran into running on windows. Boils down to:
node some/script.js
(what I've done) orcross-env
dev dep, and usecross-env some/script
where there is asome/script
with a#!
andsome/script.bat
written for windowscmd.exe
. This one is no fun.exec('node_modules/.bin/foo'...)
which doesn't work in cmd.exe (it tries to runnode_modules
with/.bin/foo
). Not quite sure about my fixes for these, I'm happy to change things..split('\n')
, which broke at least starting the emulator (looking forfoo
, not findingfoo\r
) - fixed this at the source, by replacing\r\n
on windows.android.emulator
(as opposed to.attached
) would startemulator.exe
even if it was already running which was for some reason causing it to get stuck (probably due to the output redirection to the log filelooks like some weird emulator internal issue) - workaround the issue by first checking for a running device matching the name.I also noticed
detox/scripts/build.sh android
was a little out of date while porting, is that code still used?Been running this for a while now and everything seems to be good, but there will always be something hiding.