XCODE
.brew install libimobiledevice
- open source package which is able to communicate with iOS devices.brew install ios-deploy
- for transferring iOS apps onto your device.brew install carthage
- WDA itself requires an iOS dependency manager called Carthage.
Since Appium will be automatically building the WDA app, we need to install Carthage so it is available to the WDA bootstrap process.Trust
the mac, select Display & Brightness, select Auto-Lock,
and set it to never, to ensure that the screen never locks on us mid-test.Bundle ID
, This will be the updatedWDABundleId
value that will be used in desired capabilities.
9.open Keychain Access
mac app, click on my certificates, Double click on certificate and make note of the Organization unit
xcodeOrgId
value that will be used in desired capabilities.Basic configuration is to have below capabilities passed to IOS Driver
capabilities.setCapability("xcodeOrgId", "COMPANY ORG ID");
capabilities.setCapability("xcodeSigningId", "iPhone Developer");
Sign in to developer.apple.com/account, and click Membership in the sidebar. Your Team ID appears in the Membership Information section under the team name.
Use the link below if basic configuration does not work, This will happen if a free apple developer account xcodeOrgId
is used in the desired capabilities above.
IOS REAL DEVICE SETUP – READ ME
NOTE : APPS BUILD FOR SIMULATOR WILL RUN ONLY ON SIMULATORS AND APPS BUILT FOR REAL DEVICES WILL RUN ONLY ON REAL DEVICES.
1)Original error: Could not determine Xcode version: Could not get Xcode version. /Library/Developer/Info.plist does not exist on disk.
Solution:
sudo xcode-select --reset
sudo xcode-select --switch /Applications/Xcode.app
Restart Appium Server
APPIUM INSPECTOR --> ADD DESIRED CAPABILITIES --> START SERVER --> THIS WILL START THE APP AND APPIUM INSPECTOR
Appium Documentation Locator Strategies
driver.findElement(AppiumBy.AccessibilityId(accessibilityId));
– AccessibilityId
in inspector can be used here
driver.findElement(AppiumBy.name(name));
– name
value in inspector can be used here
XPATH
value in appium Inspector can be used in driver.findElement(AppiumBy.xpath(xPath));
.
Predicate Format Strings are a typical Apple dev thing, and they also work in iOS. Predicate format strings enable basic comparisons and matching. In our case, they allow basic matching of elements according to simple criteria. What’s really useful about predicate strings is that you can combine simple criteria to form more complex matches. In the XCUITest driver, predicate strings can be used to match various element attributes, including name, value, label, type, visible, etc…
Examples:
label CONTAINS 'your label string'
label BEGINSWITH 'your label string'
name BEGINSWITH 'your name string'
label ENDSWITH 'your label string'
label == 'your label string'
driver.findElementByIosNsPredicate('type == "XCUIElementTypeTable" AND name == "table"');
driver.findElementByIosNsPredicate('type == "XCUIElementTypeTable" AND (name == "table" OR label == "tableLabel")');
driver.findElementByIosNsPredicate('type == "XCUIElementTypeTable" AND name IN {"table2","table1"}');
One example from the WebDriverAgent predicate string guide shows a fun compound predicate:
type == 'XCUIElementTypeButton' AND value BEGINSWITH[c] 'bla' AND visible == 1
This predicate string would match any visible button whose value begins with ‘bla’. How would we write this up in our Java client code? Simply by using the appropriate MobileBy method, as follows:
String selector = "type == 'XCUIElementTypeButton' AND value BEGINSWITH[c] 'bla' AND visible == 1";
driver.findElement(MobileBy.iOSNsPredicateString(selector));
Because predicate matching is built into XCUITest, it has the potential to be much faster than Appium’s XPath strategy.
The final option is a sort of hybrid between XPath and predicate strings: the -ios class chain locator strategy. This was developed by the Appium team to meet the need of hierarchical queries in a more performant way. The types of queries possible via the class chain strategy are not as powerful as those enabled by XPath, but this restriction means a better performance guarantee (this is because it is possible to map class chain queries into a series of direct XCUITest calls, rather than having to recursively build an entire UI tree). Class chain queries look very much like XPath queries, however the only allowed filters are basic child/descendant indexing or predicate string matching. It’s worth checking out the class chain docs to find a number of examples. Let’s take a look at just a couple:
XCUIElementTypeWindow[2]
selects the second window in the hierarchy.
XCUIElementTypeWindow[
label BEGINSWITH “foo”][-1]
selects the last window whose label begins with foo.
**/XCUIElementTypeCell[
name BEGINSWITH “C”]/XCUIElementTypeButton[10]
` selects the 10th child button of the first cell in the tree whose name starts with C and which has at least ten direct children of type XCUIElementTypeButton.
Just as before, there is a special MobileBy method to hook up your class chain queries in the Java client:
driver.findElement(MobileBy.iOSClassChain(selector));
ACCESSIBILITY INSPECTOR
is present at XCODE -- OPEN DEVELOPER TOOLS -- ACCESSIBILITY INSPECTOR.
This is useful in locating elements when an app installed in real device.
Coonect device , open ACCESSIBILITY INSPECTOR and select the device that you want to use.
Usage is similar to appium inspector.
One way to identify elements is to modify UserAgent
as done in andoird.Safari has built in UserAgent
in develop
tool bar options.
SETTINGS --> SAFARI --> ADVANCED --> WEBINSPECTOR
(make sure that this is enabled)DEVELOP
option from menu and select device/simulatorAppium Driver capabilities are similar to Native app except that user has to switch to web context when trying to simulate Web view user actions
driver.getConext()
—-> Will return the context of the app (WEB VIEW or NATIVE APP).
driver.getContextHandles()
—-> Will return Set of Strings similar to Window Handles in selenium.
driver.context(“give one of the String that was returned by previous getContextHandles() method”)
–> Used to Switch to Web view or Native view depending on the task.
driver.terminateApp(BUNDLE_ID);
showNotifications();
driver.findElement(By.xpath("//XCUIElementTypeCell[contains(@label, 'notification text')]"));
hideNotifications();
driver.activateApp(BUNDLE_ID);
The terminateApp and activateApp commands are self-explanatory, and simply require the bundle ID of your app.
The only mystery here is in the showNotifications and hideNotifications methods.
These are not driver methods, but rather helper methods I've implemented to take care of swiping the notifications shade down (to open) and up (to close).
The implementation currently uses the TouchAction interface to set up the swipe.
Assuming we have a field called screenSize in our test class which has previously queried the screen dimensions from Appium,
then our notifications helpers look like:
private void showNotifications() {
manageNotifications(true);
}
private void hideNotifications() {
manageNotifications(false);
}
private void manageNotifications(Boolean show) {
private Dimension screenSize = driver.manage().window().getSize();
int yMargin = 5;
int xMid = screenSize.width / 2;
PointOption top = PointOption.point(xMid, yMargin);
PointOption bottom = PointOption.point(xMid, screenSize.height - yMargin);
TouchAction action = new TouchAction(driver);
if (show) {
action.press(top);
} else {
action.press(bottom);
}
action.waitAction(WaitOptions.waitOptions(Duration.ofSeconds(1)));
if (show) {
action.moveTo(bottom);
} else {
action.moveTo(top);
}
action.perform();
}
This is all possible to encode into your Appium scripts using two handy commands: mobile: launchApp
and mobile: activateApp.
activateApp merely brings app back to the foreground. Here are examples of how we’d use these commands, by incorporating the Bundle IDs of the apps we’re dealing with (having these Bundle IDs available is a pre-requisite):
// launch the photos app (with the special bundle id seen below)
HashMap<String, Object> args = new HashMap<>();
args.put("bundleId", "com.apple.mobileslideshow");
driver.executeScript("mobile: launchApp", args);
// re-activate that AUT (in this case The App)
args.put("bundleId", "io.cloudgrey.the-app");
driver.executeScript("mobile: activateApp", args);
1. Open the .xcodeproj with Xcode
2. Select the iOS simulator by clicking the project name which is located on the top left corner (next to Stop button)
3. Select Product -> Clean
4. Select Product -> Build
5. Click on “RUN” button
6. If everything is fine we will be notified with a Build Success message and the selected simulator will open the app.
7. Use the app located at (/Users/XXX/Library/Developer/Xcode/DerivedData/XXXXXX-xxxxxxx/Build/Products/Debug-iphonesimulator/xxx.app)