Toggle WiFi on iOS using Appium from Settings app

Switch ON/OFF WiFi on iOS Device.

The code works on:
* iOS 13.6
* Appium 1.17
* XCode 11.6

Toggle WiFi using iOS Settings App

We will be using Java, Page Object Model and Cucumber to accomplish this.

  1. Firstly, declare settings app bundle ID and locators in page class and respective getter methods, refer to this link for default bundle ID’s:

PageClass.java

private String BUNDLE_ID_SETTINGS = "com.apple.Preferences";//locator for WiFi cell in settings app
private String WIFI_CELL_XPATH = "//XCUIElementTypeStaticText[@name=\"Wi-Fi\"]";
//locator for WiFi switch to turn on/off
private String WIFI_SWITCH_XPATH = "//XCUIElementTypeSwitch[@name=\"Wi-Fi\"]";
public String getSettingsBundleID() { return BUNDLE_ID_SETTINGS; }public MobileElement getWiFiCell() { return MobileConnector.getDriver().findElementByXPath(WIFI_CELL_XPATH); }public MobileElement getWifiSwitch() { return MobileConnector.getDriver().findElementByXPath(WIFI_SWITCH_XPATH); }//method to get current WiFi status
public String getWifiStatus()
{
String wifiStatus = null;
do {
wifiStatus = getWifiSwitch().getAttribute("value");
} while (wifiStatus == null);
System.out.println("Current WiFi Status: " + wifiStatus);
return wifiStatus;
}

2. Second, we need to create step definition method for cucumber step, lets name cucumber step:

[Commons] Turn WiFi OFF

Step_Definition.java

import java.util.HashMap;

@When("^\\[Commons] Turn WiFi OFF$")
public void turnOffWifi() throws InterruptedException
{
// put settings app bundle ID
HashMap<String, Object> iOSSettingsAppArgs = new HashMap<>();
iOSSettingsAppArgs.put("bundleId", getPageClass().getSettingsBundleID());

// terminating app in case its already launched, need initial launch every time
getDriver().executeScript("mobile: terminateApp", iOSSettingsAppArgs);

// launching settings app
getDriver().executeScript("mobile: launchApp", iOSSettingsAppArgs);

// navigate to WiFi section
getPageClass().getWiFiCell().click();

// checking if WiFi is ON before turning it OFF
if (getPageClass().getWifiStatus().equalsIgnoreCase("1"))
{
System.out.println("WIFI turned ON, Turning it OFF ..");
do {
// throw WiFi switch to turn OFF
getPageClass().getWifiSwitch().click();
Thread.sleep(2000);
} while (getPageClass().getWifiStatus().equalsIgnoreCase("1"));
}else if (getPageClass().getWifiStatus().equalsIgnoreCase("0")) {
System.out.println("WIFI already OFF ..");
}

// terminate Settings app
getDriver().executeScript("mobile: terminateApp", iOSSettingsAppArgs);
}

Similar method can be used to turn ON WiFi with a little tweaking:

Cucumber Step:

[Commons] Turn WiFi ON

Step_Definition.java

import java.util.HashMap;

@When("^\\[Commons] Turn WiFi ON$")
public void turnONWifi() throws InterruptedException
{
// put settings app bundle ID
HashMap<String, Object> iOSSettingsAppArgs = new HashMap<>();
iOSSettingsAppArgs.put("bundleId", getPageClass().getSettingsBundleID());

// terminating app in case its already launched, need initial launch every time
getDriver().executeScript("mobile: terminateApp", iOSSettingsAppArgs);

// launching settings app
getDriver().executeScript("mobile: launchApp", iOSSettingsAppArgs);

// navigate to WiFi section
getPageClass().getWiFiCell().click();

// checking if WiFi is OFF before turning it ON
if (getPageClass().getWifiStatus().equalsIgnoreCase("0"))
{
System.out.println("WiFi turned OFF, Turning it ON ..");
do {
// throw WiFi switch to turn ON
getPageClass().getWifiSwitch().click();
Thread.sleep(2000);
} while (getPageClass().getWifiStatus().equalsIgnoreCase("0"));
}else if (getPageClass().getWifiStatus().equalsIgnoreCase("1")) {
System.out.println("WiFi already ON ..");
}

// terminate Settings app
getDriver().executeScript("mobile: terminateApp", iOSSettingsAppArgs);
}

Similarly you can toggle Airplane Mode, Bluetooth and Cellular features.

Goodluck!