diff --git a/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/WebDriverAgentRunner.xcscheme b/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/WebDriverAgentRunner.xcscheme
index 8857b934c..4c2919f78 100644
--- a/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/WebDriverAgentRunner.xcscheme
+++ b/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/WebDriverAgentRunner.xcscheme
@@ -66,6 +66,11 @@
value = "$(USE_PORT)"
isEnabled = "YES">
+
+
+
+
0) {
+ return NSProcessInfo.processInfo.environment[@"USE_IP"];
+ }
+
+ return nil;
+}
+
+ (NSInteger)mjpegServerPort
{
if (self.mjpegServerPortFromArguments != NSNotFound) {
diff --git a/WebDriverAgentTests/UnitTests/FBConfigurationTests.m b/WebDriverAgentTests/UnitTests/FBConfigurationTests.m
index 05e53d65f..6d25ea6b0 100644
--- a/WebDriverAgentTests/UnitTests/FBConfigurationTests.m
+++ b/WebDriverAgentTests/UnitTests/FBConfigurationTests.m
@@ -20,6 +20,7 @@ - (void)setUp
{
[super setUp];
unsetenv("USE_PORT");
+ unsetenv("USE_IP");
unsetenv("VERBOSE_LOGGING");
}
@@ -45,4 +46,15 @@ - (void)testVerboseLoggingEnvironmentOverwrite
XCTAssertTrue([FBConfiguration verboseLoggingEnabled]);
}
+- (void)testBindingIPDefault
+{
+ XCTAssertNil([FBConfiguration bindingIPAddress]);
+}
+
+- (void)testBindingIPEnvironmentOverwrite
+{
+ setenv("USE_IP", "192.168.1.100", 1);
+ XCTAssertEqualObjects([FBConfiguration bindingIPAddress], @"192.168.1.100");
+}
+
@end
diff --git a/lib/types.ts b/lib/types.ts
index ee5cdf996..32a32493b 100644
--- a/lib/types.ts
+++ b/lib/types.ts
@@ -64,6 +64,7 @@ export interface WebDriverAgentArgs {
wdaLocalPort?: number;
wdaRemotePort?: number;
wdaBaseUrl?: string;
+ wdaBindingIP?: string;
prebuildWDA?: boolean;
webDriverAgentUrl?: string;
wdaConnectionTimeout?: number;
@@ -116,6 +117,7 @@ export interface XcodeBuildArgs {
useXctestrunFile?: boolean;
launchTimeout?: number;
wdaRemotePort?: number;
+ wdaBindingIP?: string;
updatedWDABundleId?: string;
derivedDataPath?: string;
mjpegServerPort?: number;
diff --git a/lib/utils.js b/lib/utils.js
index 4ff845abd..3d0bb3ec0 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -166,6 +166,16 @@ async function setRealDeviceSecurity (keychainPath, keychainPassword) {
* @property {string} platformVersion - The platform version of OS.
* @property {string} platformName - The platform name of iOS, tvOS
*/
+
+/**
+ * Arguments for setting xctestrun file
+ * @typedef {Object} XctestrunFileArgs
+ * @property {DeviceInfo} deviceInfo - Information of the device under test
+ * @property {string} sdkVersion - The Xcode SDK version of OS.
+ * @property {string} bootstrapPath - The folder path containing xctestrun file.
+ * @property {number|string} wdaRemotePort - The remote port WDA is listening on.
+ * @property {string} [wdaBindingIP] - The IP address to bind to. If not given, it binds to all interfaces.
+ */
/**
* Creates xctestrun file per device & platform version.
* We expects to have WebDriverAgentRunner_iphoneos${sdkVersion|platformVersion}-arm64.xctestrun for real device
@@ -174,19 +184,17 @@ async function setRealDeviceSecurity (keychainPath, keychainPassword) {
* e.g. Xcode which has iOS SDK Version 12.2 on an intel Mac host machine generates WebDriverAgentRunner_iphonesimulator.2-x86_64.xctestrun
* even if the cap has platform version 11.4
*
- * @param {DeviceInfo} deviceInfo
- * @param {string} sdkVersion - The Xcode SDK version of OS.
- * @param {string} bootstrapPath - The folder path containing xctestrun file.
- * @param {number|string} wdaRemotePort - The remote port WDA is listening on.
+ * @param {XctestrunFileArgs} args
* @return {Promise} returns xctestrunFilePath for given device
* @throws if WebDriverAgentRunner_iphoneos${sdkVersion|platformVersion}-arm64.xctestrun for real device
* or WebDriverAgentRunner_iphonesimulator${sdkVersion|platformVersion}-x86_64.xctestrun for simulator is not found @bootstrapPath,
- * then it will throw file not found exception
+ * then it will throw a file not found exception
*/
-async function setXctestrunFile (deviceInfo, sdkVersion, bootstrapPath, wdaRemotePort) {
+async function setXctestrunFile (args) {
+ const {deviceInfo, sdkVersion, bootstrapPath, wdaRemotePort, wdaBindingIP} = args;
const xctestrunFilePath = await getXctestrunFilePath(deviceInfo, sdkVersion, bootstrapPath);
const xctestRunContent = await plist.parsePlistFile(xctestrunFilePath);
- const updateWDAPort = getAdditionalRunContent(deviceInfo.platformName, wdaRemotePort);
+ const updateWDAPort = getAdditionalRunContent(deviceInfo.platformName, wdaRemotePort, wdaBindingIP);
const newXctestRunContent = _.merge(xctestRunContent, updateWDAPort);
await plist.updatePlistFile(xctestrunFilePath, newXctestRunContent, true);
@@ -197,16 +205,17 @@ async function setXctestrunFile (deviceInfo, sdkVersion, bootstrapPath, wdaRemot
* Return the WDA object which appends existing xctest runner content
* @param {string} platformName - The name of the platform
* @param {number|string} wdaRemotePort - The remote port number
- * @return {object} returns a runner object which has USE_PORT
+ * @param {string} [wdaBindingIP] - The IP address to bind to. If not given, it binds to all interfaces.
+ * @return {object} returns a runner object which has USE_PORT and optionally USE_IP
*/
-function getAdditionalRunContent (platformName, wdaRemotePort) {
+function getAdditionalRunContent (platformName, wdaRemotePort, wdaBindingIP) {
const runner = `WebDriverAgentRunner${isTvOS(platformName) ? '_tvOS' : ''}`;
-
return {
[runner]: {
EnvironmentVariables: {
// USE_PORT must be 'string'
- USE_PORT: `${wdaRemotePort}`
+ USE_PORT: `${wdaRemotePort}`,
+ ...(wdaBindingIP ? { USE_IP: wdaBindingIP } : {}),
}
}
};
diff --git a/lib/webdriveragent.js b/lib/webdriveragent.js
index 7e3f88f07..a48f79626 100644
--- a/lib/webdriveragent.js
+++ b/lib/webdriveragent.js
@@ -60,7 +60,7 @@ export class WebDriverAgent {
this.wdaRemotePort = ((this.isRealDevice ? args.wdaRemotePort : null) ?? args.wdaLocalPort)
|| WDA_AGENT_PORT;
this.wdaBaseUrl = args.wdaBaseUrl || WDA_BASE_URL;
-
+ this.wdaBindingIP = args.wdaBindingIP;
this.prebuildWDA = args.prebuildWDA;
// this.args.webDriverAgentUrl guiarantees the capabilities acually
@@ -104,6 +104,7 @@ export class WebDriverAgent {
updatedWDABundleId: this.updatedWDABundleId,
launchTimeout: this.wdaLaunchTimeout,
wdaRemotePort: this.wdaRemotePort,
+ wdaBindingIP: this.wdaBindingIP,
useXctestrunFile: this.useXctestrunFile,
derivedDataPath: args.derivedDataPath,
mjpegServerPort: this.mjpegServerPort,
@@ -390,6 +391,9 @@ export class WebDriverAgent {
if (this.mjpegServerPort) {
xctestEnv.MJPEG_SERVER_PORT = this.mjpegServerPort;
}
+ if (this.wdaBindingIP) {
+ xctestEnv.USE_IP = this.wdaBindingIP;
+ }
this.log.info('Launching WebDriverAgent on the device without xcodebuild');
if (this.isRealDevice) {
// Current method to launch WDA process can be done via 'xcrun devicectl',
diff --git a/lib/xcodebuild.js b/lib/xcodebuild.js
index 8a25361d0..927987f8d 100644
--- a/lib/xcodebuild.js
+++ b/lib/xcodebuild.js
@@ -83,6 +83,7 @@ export class XcodeBuild {
this.launchTimeout = args.launchTimeout;
this.wdaRemotePort = args.wdaRemotePort;
+ this.wdaBindingIP = args.wdaBindingIP;
this.updatedWDABundleId = args.updatedWDABundleId;
this.derivedDataPath = args.derivedDataPath;
@@ -116,12 +117,13 @@ export class XcodeBuild {
platformVersion: this.platformVersion || '',
platformName: this.platformName || ''
};
- this.xctestrunFilePath = await setXctestrunFile(
- deviceInfo,
- this.iosSdkVersion || '',
- this.bootstrapPath,
- this.wdaRemotePort || 8100
- );
+ this.xctestrunFilePath = await setXctestrunFile({
+ deviceInfo,
+ sdkVersion: this.iosSdkVersion || '',
+ bootstrapPath: this.bootstrapPath,
+ wdaRemotePort: this.wdaRemotePort || 8100,
+ wdaBindingIP: this.wdaBindingIP
+ });
return;
}