Closed marekcirkos closed 8 years ago
Unfortunately this is quite different. applicationDataPath
requires path to xcappdata
that is prepared in certain way.
I got good news for you tho:
xcappdata
,Hi @marekcirkos
I tried to create xcappdata by XCode, also hardcode platformDirectory on "FBApplicationDataPackageBuilder" point to "iPhoneOS.platform"
However I still cannot connect to test bundle (I got timeout), event I tried to load private testing frameworks. Tomorrow, I'll try to resolve it and give you a log file
if (!self.platformDirectory) {
self.platformDirectory = @"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform";
}
if (self.platformDirectory) {
XCTestFrameworkPath = [self.platformDirectory stringByAppendingPathComponent:@"Developer/Library/Frameworks/XCTest.framework"];
IDEBundleInjectionFrameworkPath = [self.platformDirectory stringByAppendingPathComponent:@"Developer/Library/PrivateFrameworks/IDEBundleInjection.framework"];
testBundlePath = self.testBundle.path;
workingDirectory = packageBundlePath;
}
Ok to give you quick unblocking information:
Hi @marekcirkos
I tried to setup the paths follow your hint and do some more tricks on FBApplicationDataPackage
self.platformDirectory = @"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform";
if (self.platformDirectory) {
NSAssert(self.platformDirectory, @"platformDirectory is required to create data package");
XCTestFrameworkPath = [self.platformDirectory stringByAppendingPathComponent:@"Developer/Library/Frameworks/XCTest.framework"];
IDEBundleInjectionFrameworkPath = [self.platformDirectory stringByAppendingPathComponent:@"Developer/Library/PrivateFrameworks/IDEBundleInjection.framework"];
testBundlePath = self.testBundle.path;
workingDirectory = packageBundlePath;
}
Now and can prepare strategy for real device. However I still cannot connect to test bundle Result:
Expected: I got message "Got proxy channel request from test bundle"
Actually: I got message "startTestManagerWithAttributes error:Error Domain=com.facebook.XCTestBootstrap Code=0 "Failed connect to test runner or test manager daemon" UserInfo={NSLocalizedDescription=Failed connect to test runner or test manager daemon}"
Log: XCBootstrap_device: https://gist.github.com/nghiadhd/e9fb82d1c0a8c07d6533fe2b65acbaa8 XCBootstrap_simulator: https://gist.github.com/nghiadhd/1695282491127b381e8a5140f78eead9
I also tried to debug on DTXTransport & DTXConnection but cause's by lacking document so I still don't know how to use them in correct way
@marekcirkos I know DTXConnectionServices & XCTest are private frameworks, so no any document from Apple. But if you have any draft document, please share with me because target is use lockdown protocol base on DTXConnectionServices to communicate with testmanagerd & xctest
@nghiadhd @marekcirkos I can invoke WebDriverAgent by XCTestBootstrap on real device after some hard-codes. The necessary thing is code sign that needs to resign all bundles in .xcappdata. Let's see my workaround at line
-withCodesignProvider:self.codesignProvider]
+withCodesignProvider:[FBCodeSignCommand codeSignCommandWithIdentityName:@"My identity name"]]
More logs if you configure correct:
/path/to/your.xcappdata/AppData/tmp/WebDriverAgentRunner.xctest: replacing existing signature /path/to/your.xcappdata/AppData/tmp/XCTest.framework: replacing existing signature /path/to/your.xcappdata/AppData/tmp/IDEBundleInjection.framework: replacing existing signature
Notice: Please run security find-identity
command to find your identity name.
@marekcirkos
applicationPath is a path to application you want to use to execute test runner (can't be tested application). You can use a dummy app that does nothing.
In my side, it doesn't respond when use dummy app. For example: I don't see the respond when I post curl -X POST $JSON_HEADER -d "" $DEVICE_URL/homescreen
message.
It works well if applicationPath is pointed to WebDriverAgentRunner-Runner.app.
Thanks @ledinhphuong
Now I can invoke WebDriverAgent on real device Notice: the applicationPath, applicationDataPath and testBundlePath must be pointed to same application (WebDriverAgent), else I got security issue
Jul 1 13:54:26 iPhone-6 cloudd[142] <Error>: <CKDGetRecordZonesURLRequest: 0x1256bc490> Failed to get push token.
Jul 1 13:54:26 iPhone-6 securityd[98] <Error>: securityd_xpc_dictionary_handler cloudd[142] copy_matching Error Domain=NSOSStatusErrorDomain Code=-50 "query missing class name" UserInfo={NSDescription=query missing class name}
Jul 1 13:54:26 iPhone-6 cloudd[142] <Error>: SecOSStatusWith error:[-50] Error Domain=NSOSStatusErrorDomain Code=-50 "query missing class name" UserInfo={NSDescription=query missing class name}
Now, hopefully @marekcirkos support auto gen .xcappdata
security find-identity
is something that XCTestBootstrap
could run in the absence of an explicit identity passed via a constructor. Using an identity from this output should hopefully provide a 'reasonable default' for codesigning.
Let me stress again that FBDeviceTestPreparationStrategy
assumes that all bundles are prepared and codesigned already. Were are working on separate strategy that will take care of that part as well.
@ledinhphuong @nghiadhd Pointing applicationPath to WebDriverAgentRunner-Runner.app
might not be a good idea as it will also load xctest bundle. We use stab app application that only prevents from being killed or being put into background (then WDA stops responding).
@marekcirkos Regard to signCode identity, I think we can pass it via command-line arguments or sign all bundles manually in .xcappdata (we should skip prepare application bundle steps)
Otherwise If we point to dummy application, may info from .xctest and info from .xcappdata don't match (name or bundlID) and cause securityd issue. I'll continue investigate and inform you if I have any result
Hi @marekcirkos
Today I tried to run XCTestBootstrap (startTestManagerWithAttributes) for multiple real devices concurrently.
However I got issue
[Error Domain=com.facebook.XCTestBootstrap Code=0 "Failed to determine test runner process PID" UserInfo={NSLocalizedDescription=Failed to determine test runner process PID}]
I debug and see that these error devices block at "testmanagerd handled session request using protcol version" message. I expected they have got "Got proxy channel request from test bundle" but not yet
Do you have any idea to resolve it?
What iOS version was it?
@marekcirkos
I confirm that if I use XCTestBootstrap to invoke test runner at the same time for 6 devices, only one device can be handshake with testmanagerd, other devices got exception. But if I start one by one, it works well
iPhone 6s: iOS 9.3.4 iPhone 6: iOS 9.3.2 iPhone 5s: iOS 9.3.4 iPad mini 2: iOS 9.3.4 iPad Air 2: iOS 9.0.2 iPhone 5: iOS 9.3.1
Closing due to inactivity. Feel free to reopen with more information or discussion.
@marekcirkos @nghiadhd @ledinhphuong it there any chance that you share your code snippets?
@marekcirkos, Does FB have a plan to implement the fbsimctl on real devices?
@wacban might have some insights on this one
I've just landed some changes that make it easier to bootstrap using a swift script wrapper of the underlying API.
From this is should be pretty trivial to make a Swift script that uses the FBSimulatorControl
and FBDeviceControl
APIs to bootstrap a WebDriverAgent
test bundle.
Here's a rough draft of what this could look like in FBSimulatorControl
:
#!/usr/bin/env xcrun swift -F /usr/local/Frameworks
import Foundation
import FBSimulatorControl
import XCTestBootstrap
// Create the FBSimulatorControl Instance.
let options = FBSimulatorManagementOptions()
let config = FBSimulatorControlConfiguration(deviceSetPath: nil, options: options)
let logger = FBControlCoreGlobalConfiguration.defaultLogger()
let control = try FBSimulatorControl.withConfiguration(config, logger: logger)
// Extract the Arguments
let arguments = Array(ProcessInfo.processInfo.arguments.suffix(3))
let udid = arguments[0]
let wdaBundle = arguments[1]
let port = arguments[2]
// Get the Target
let query = FBiOSTargetQuery.udids([udid])
let results = control.set.query(query)
let simulator = results.first!
print("Using \(simulator)")
// If it is booted, keep it booted, otherwise boot it.
if (simulator.state != .booted) {
print("Booting Simulator \(simulator)")
try simulator.bootSimulator()
}
// List the Installed Apps and get the first installed app
let applications = simulator.installedApplications()
let application = applications.first!
// Configure an App Launch
let appLaunch = FBApplicationLaunchConfiguration(
application: application,
arguments: ["--port", port],
environment: [:],
output: FBProcessOutputConfiguration.outputToDevNull()
)
// Wrap this in a Test Launch Configuration
let testLaunch = FBTestLaunchConfiguration(testBundlePath: wdaBundle)
.withApplicationLaunchConfiguration(appLaunch)
.withUITesting(true)
// Start the Test Launch
print("Launching \(application)")
try simulator.startTest(with: testLaunch)
try simulator.waitUntilAllTestRunnersHaveFinishedTesting(withTimeout: 100000000)
This assumes that you have:
1) Installed fbsimctl
from HEAD
using brew install fbsimctl --HEAD
(this path is important in the !#
2) Invoke the script with a valid UDID, WebDriverAgent.xctest
bundle and a port number for WebDriverAgent
to bind on.
An invocation would look something like this:
./bootstrap_wda.swift 9B865108-DF0F-4731-AEEC-01EF24146929 /path/to/WebDriverAgentRunner.xctest 8090
Which would launch WebDriverAgent
for the simulator 9B865108-DF0F-4731-AEEC-01EF24146929
, launching the prebuild WebDriverAgent.xctest
bundle at /path/to/WebDriverAgentRunner.xctest
, with WebDriverAgent
binding on port 8090
.
It should be possible to build something equivalent for FBDeviceControl
, but with the appropriate APIs available to you.
Moved issue from https://github.com/facebook/WebDriverAgent/issues/114#issuecomment-229023492
@marekcirkos After investigate the fbsimctl sources and flows. I'm starting to port fbsimctl to fbdevicectl. However I'm stuck at FBXCTestPreparationStrategy
(instancetype)strategyWithApplicationPath:(NSString )applicationPath applicationDataPath:(NSString )applicationDataPath testBundlePath:(NSString *)testBundlePath; Could I confirm sth?
applicationPath: is path to .app which is generated by Xcode after build test applicationDataPath: is path to .xcappdata which is download by Xcode -> Window -> Devices -> DownloadContainer testBundlePath: is path to .xctest that is subfolder in *.app Otherwise, in testBundlePath for real device doesn't have .xctestconfiguration
Here is structure of *.app
WebDriverAgentRunner-Runner.app