Talking with LeoNatan in #629 I mentioned Facebook released a new tool that replacesincludes fbsimctl that is called idb. They will start monitoring and updating that repo instead of the other one and they are suggesting everyone to move to this new tool instead. So it will be great if Detox could migrate as well!
Currently it's under construction but as it supposedly fixes some issues that fbsimctl has, I might as well suggest it here.
Here is the repo for idb : https://github.com/facebook/idb
Note: This tool is only for iOS, I assume it's the equivalent of adb for Android?
Thanks!
Hello, one of the authors of the idb project here!
More than happy to give pointers/advice if you need them.
As far as the maturity of the project goes, we've been using this in production for nearly 2 years now and it's only just now that we've open sourced it.
Hey @lawrencelomax !!
Good to have you here, actually I do have a few questions:
idb can get us closer, this may change they way we approach it. here's the latest status written by @LeoNatan https://github.com/wix/Detox/issues/95#issuecomment-483348724.One of the reason that made us ditch fbsimctl (aside from the multi simulator support introduced in Xcode9) was the fact that there were no stable releases, and the only way to install it was through brew at the repo's HEAD. I see that idb is being released regularly, and brew uses the latest version, which is great!
I hear you on this as know that this has been a problem in the past. The biggest reason for this is that fbsimctl was very much in maintenance mode whilst we were working on idb itself. We're more than happy to keep changelogs and make regular releases from master.
I did not dive into the code, but couldn't find anything in docs regarding ability to pass launch args and environment variables to app on device, Is that possible?
Device App launching has some interesting constraints, including the app must be a dev build but we do support passing environment variables. This is because the only way of launching an application on a device is to treat it as a debug session, even if you're not interested in running debugger commands.
I think one area that we would need to figure out is the dylib injection that detox uses on sims. The dylib would need to be codesigned and included in the Application bundle. You can't load a dylib on devices unless it's part of Apple's developer tools (i.e. how the view debugger works) or if it's part of the application bundle (i.e. how test bundles work).
You may want to check out how things such as Reveal do this as IIRC they use dylib injection in a similar way to how you'd be interested in doing it in Detox.
Thanks for commenting.
We have always known that signing will be a requirement for running on device. My idea has always been to deduce the signing identity from the user's project and then attempt to sign it with the Detox framework and touched entitlements. This is probably less suitable for device labs, where the signing certificate may not be present on the machine running the test, but since there is no escape from signing, I don't think there is any other way.
What the Reveal guys are doing is to include an integration script that does the heavy lifting (similar to what we do in Detox Instruments). This still requires some changes to the user project. We may go down that road, but it is not planned yet (attaching Detox has repercussions, even if tests are not running).
Hi! We are having trouble setting our app's location for testing with Detox, so I wanted to ask for help figuring it out.
In our init.js configuration's beforeAll we have:
beforeAll(async () => {
await detox.init(config, {
launchApp: false,
})
await device.launchApp({
permissions: {
notifications: 'YES',
location: 'always',
},
})
await device.setLocation(32.0853, 34.7818)
})
The device.setLocation seems to not be working, it just stays at the current location. We know this needs fbsimctl to work but I know it's deprecated and now part of idb and wanted to know if there is a chance this was somewhat implemented on an latest update, otherwise I would like to know the proper way to address this case.
Thanks!
Hello,
Unfortunately, I didn't implement idb support in Detox. I did play a little with the tool and was met with some issues. It felt to me that the tool is not ready yet. That was a while back, but I have not had time to further investigate.
PRs are welcome.
I'd say "as a workaround, use fbsimctl for now", but idb seems to be incompatible with fbsimctl... 😂
Instead, don't call setLocation. Obtain the device identifier from the device internals and run the idb command directly inside your test, providing the device identifier as input to the command.
@LeoNatan how would you recommend running the idb command inside the test? Making a script that runs along with detox test or do you mean adding that command somehow inside each test?
I've tried running idb set-location command by its own and it works, but doesn't if I run a test with Detox. Also, where would you add the device identifier to that command? I believe it only receives LAT LONG. https://www.fbidb.io/docs/commands#set-a-simulators-location
Detox tests run in node, so you can use standard node facilities to call idb manually.
Regarding device identifier, could be that the entire simulator runtime uses the same coordinates, so a specific device needs not be provided. That makes your life even easier, because you don't need to find the device identifier from the Detox internals. So just call the set-location command where you need to using node API.
in case anyone was wondering how to do it, after installing idb replaced my device.setLocation call with:
exec("idb list-targets | grep -n 'Booted'", (err, stdout, stderr) => {
console.log("idb list-targets - ", err, stdout, stderr);
const tempDevice = stdout.split("|")[1].trim();
exec(
"idb set-location --udid " + tempDevice + " 32.0853 34.7818",
(err, stdout, stderr) => {
console.log("setLocation - ", err, stdout, stderr);
}
);
});
Please note that you should not assume only one booted device, or apply to all booted. It’s best to extract the current sim udid from internals.
How would one go about using the internals?
I've tried @OisinOKeeffe approach and whenever I run a test, it spends a lot of time to even start the first test, and then when it finishes, every test has failed even though I saw it pass. I have a coulple of errors in my console:
First, it says that signal 4 was flaged
4 Detox 0x00000001087fa776 -[DetoxManager notifyOnCrashWithDetails:] + 293
It also fails every test with a timeout (which I believe is the time it takes to even start the test suite):
Timeout - Async callback was not invoked within the 120000ms timeout specified by jest.setTimeout.Error: Timeout - Async callback was not invoked within the 120000ms timeout specified by jest.setTimeout.
Also, some of the tests say that the app crashed because we should only have exactly one subview and that is why they fail.
The logs that @OisinOKeeffe puts in the code bring me this:
console.log e2e/init.js:27
idb list-targets - null 21:iPhone XÊ€ | F4941326-C918-4242-9882-A1388CFFF1FE | Booted | simulator | iOS 12.4 | x86_64 | :0
console.log e2e/init.js:30
setLocation -
Despite all this, I can see location has changed to the one I selected ¯_(ツ)_/¯
You can obtain the device id using device._deviceId.
The crash doesn’t seem related to me.
I was able to fix it by writing it this way:
const { stdout, stderr } = await exec("idb list-targets | grep -n 'Booted'")
console.log('idb list-targets - ', stdout, stderr)
const tempDevice = stdout.split('|')[1].trim()
exec(`idb set-location --udid ${tempDevice} 40.6501 -73.94958`)
console.log('setLocation - ', stdout, stderr)
@OisinOKeeffe how do you run the idb companion? Manually, before the test suite? Without it, set-location does not work. I would like to know if there is an easier way for it than executing it everytime.
Instead of using the booted device, try the following line:
const tempDevice = device._deviceId
Very cool, based off of @LeoNatan's response I think I am going to do the following to make sure I am targeting the right device.
exec(idb set-location --udid ${device._deviceId} 40.6501 -73.94958)
@ayelenmarie when I ran my test all I had to do was ensure that the aforementioned was run in place of device.setLocation and my simulator location was updated without having to do anything else. Why would I need to run idb companion?
@OisinOKeeffe mine does not work unless I don't have that simulator's companion running. Which version of fb-idb did you install with pip?
@ayelenmarie I wasn't following until today when I attempted to execute the idb command again and got some message about not being able to connect to the bridge. After some troubleshooting a restart seems to have cleared up my issue and I am able to execute the command again without any issue.
Try idb kill followed by idb daemon and if the latter fails restart and try idb set-location --udid {your device udid} 40.6501 -73.94958 and it should work.
It works now! Thanks @OisinOKeeffe for your insight. Restarting it worked for me as well as the idb kill.
@LeoNatan aside from device._deviceId, is there any other information available from the simulator that is running Detox? Such as the name or the OS. IT should be helpful to log it instead of the ID, so it's easier to check.
I don't think so.
@noomorph ?
its not details on the simulator but you can access details of the detox config that is being run like so (here I am accessing the type )
device._deviceConfig.type
Hi, hopping on the conversation since the problems I just started having led me here.
export const launchApp = async (launchParams) => {
await device.launchApp({
newInstance: true,
permissions: {
notifications: 'YES',
location: 'inuse'
},
...launchParams
});
await device.setLocation(office.lat, office.lon);
};
detox[15258] ERROR: [exec.js/EXEC_FAIL, #15] "fbsimctl 2BC36BD5-6557-49EF-A693-40A4336FCB4B set_location 6.9055934 79.8545685" failed with code = 1, stdout and stderr:
detox[15258] ERROR: [exec.js/EXEC_FAIL, #15]
detox[15258] ERROR: [exec.js/EXEC_FAIL, #15] '["2BC36BD5-6557-49EF-A693-40A4336FCB4B", "set_location", "6.9055934", "79.8545685"]' does not match '[fbsimctl print [action]
To my knowledge so far, I'm running into errors due to fbsimctl not being compatible or updated in a long time. (I'm testing against iPhone X, iOS 13.0)
fbsimctl is deprecated in favour of idb.
Detox has not yet made this move hence relying on fbsimctl still which is kind of 'broken'.
Therefore, for the moment the best course of action would be to install idb, implement,
const setLocation = async (latitude, longitude) => {
const { stdout, stderr } = await exec("idb list-targets | grep -n 'Booted'");
console.log('idb list-targets - ', stdout, stderr);
// const tempDevice = stdout.split('|')[1].trim();
exec(`idb set-location --udid ${device._deviceId} ${latitude} ${longitude}`);
console.log('setLocation - ', stdout, stderr);
};
(Thanks @ayelenmarie and @OisinOKeeffe )
and use it like so until Detox start using idb.
...
// await device.setLocation(office.lat, office.lon);
await setLocation(office.lat, office.lon);
...
Does that sound about right?
I tried idb and lyft/set-simulator-location, none of them work when the ios simulator is running headless (like on CircleCI) =(
Yeah, it seems idb is a broken mess. I'm wondering whether I should downgrade Detox at this point, not sure whether it would help.
It might be a limitation of the simulator runtime.
For people coming here, here is how to install idb before using @JanithaR workaround
brew tap facebook/fb
brew install idb-companion
pip install fb-idb
And don't forget to import exec if you are running function from the same js file as a main detox setup:
import { exec } from 'child_process';
@ayelenmarie @LeoNatan Thanks for your input on this issue, it has been quite helpful. I've been rummaging for days on how to first get fbsimctl to work and finally hit upon your thread and accordingly dumped it for idb.
I had issues with finding idb on the system and had to hardcode the absolute path to the binary, otherwise it was failing silently and the stdout you had doesn't really show me the error... The way I got it running was as follows:
const idbPATH = '/Users/myuser/Library/Python/3.8/bin/';
await exec(
`${idbPATH}idb set-location --udid ${device._deviceId} ${latitude} ${longitude}`,
(error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
},
);
had the same issue with idb, I had to use something like export PATH="$HOME/Library/Python/3.8/bin:$PATH" in my bash_profile to add all those python libraries binaries (including idb) to my $PATH env variable.
Most helpful comment
Hi, hopping on the conversation since the problems I just started having led me here.
To my knowledge so far, I'm running into errors due to fbsimctl not being compatible or updated in a long time. (I'm testing against iPhone X, iOS 13.0)
fbsimctl is deprecated in favour of idb.
Detox has not yet made this move hence relying on fbsimctl still which is kind of 'broken'.
Therefore, for the moment the best course of action would be to install idb, implement,
(Thanks @ayelenmarie and @OisinOKeeffe )
and use it like so until Detox start using idb.
Does that sound about right?