- Created by Phil Gochenour, last modified by Kim Pohas on Jan 20, 2021
If you're looking for specific language and/or framework examples, please explore the demo repos below:
Below are appium/real device-specific examples from each repo:
IOSNativeAppUnifiedPlatformTest.java (source from Sauce Labs Training Java)
Java11 Junit4 iOS Example
Expand source
package com.realdevice.unifiedplatform; import io.appium.java_client.AppiumDriver; import io.appium.java_client.MobileElement; import io.appium.java_client.ios.IOSDriver; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; import org.openqa.selenium.By; import org.openqa.selenium.MutableCapabilities; import java.net.MalformedURLException; import java.net.URL; import static org.junit.Assert.assertTrue; public class IOSNativeAppUnifiedPlatformTest { @Rule public TestName name = new TestName() { public String getMethodName() { return String.format("%s", super.getMethodName()); } }; private AppiumDriver<MobileElement> driver; public AppiumDriver<MobileElement> getDriver() { return driver; } @Before public void setUp() throws MalformedURLException { MutableCapabilities capabilities = new MutableCapabilities(); capabilities.setCapability("idleTimeout", "90"); capabilities.setCapability("noReset", "true"); capabilities.setCapability("newCommandTimeout", "90"); capabilities.setCapability("language", "en"); capabilities.setCapability("platformName", "iOS"); //Not specifying platformVersion or the exact device is the most likely to //find a device in the cloud capabilities.setCapability("deviceName", "iPhone.*"); capabilities.setCapability("name", name.getMethodName()); capabilities.setCapability("app", "storage:filename=" + "iOS.RealDevice.Sample.ipa"); driver = new IOSDriver( new URL("https://" + System.getenv("SAUCE_USERNAME") + ":" + System.getenv("SAUCE_ACCESS_KEY") + "@ondemand.us-west-1.saucelabs.com/wd/hub"), capabilities); } @After public void tearDown() { if (getDriver() != null) { getDriver().quit(); } } @Test public void shouldOpenApp() { assertTrue(getDriver().findElement(By.id("test-LOGIN")).isDisplayed()); } }
wdio.ios.sauce.real.conf.js (source from Sauce Labs Training JavaScript)
WebdriverIO Example config
Expand source
const {config} = require('./wdio.shared.sauce.conf'); // ============ // Capabilities // ============ // For all capabilities please check // http://appium.io/docs/en/writing-running-appium/caps/#general-capabilities config.capabilities = [ { deviceName: 'iPhone XS', platformName: 'iOS', orientation: 'PORTRAIT', // The path to the app that has been uploaded to the Sauce Storage, // see https://wiki.saucelabs.com/display/DOCS/Application+Storage for more information app: 'storage:filename=sample-app-ios.ipa', // Keep the device connected between tests so we don't need to wait for the cleaning process cacheId: 'jsy1v49pn10', newCommandTimeout: 240, // Always default the language to a language you prefer so you know the app language is always as expected language: 'en', locale: 'en', // Add a name to the test name: 'Appium Gestures', }, ]; exports.config = config;
exercises.spec.js (source from Sauce Labs Training JavaScript)
WebdriverIO Example spec
Expand source
// // ================================================================== // We are using accessibilityId's here so easily select elements for // Android and iOS in a cross-platform way // This project is not using a PageObject model because it's not part // if the scope of this exercise // ================================================================== // describe('Appium Gestures Exercises', () => { // This will be executed for every test, log in and verify that the // correct screen is loaded beforeEach(() => { // Wait for the App to be opened $('~test-Login').waitForDisplayed(); // Login in and wait for the items screen is visible $('~test-Username').addValue('standard_user'); $('~test-Password').addValue('secret_sauce'); $('~test-LOGIN').click(); $('~test-PRODUCTS').waitForDisplayed(); }); // This will be executed after each test afterEach(() => { // Restart the app after each test driver.reset(); }); it('should be able to do a scroll with TouchPerform', () => { // 1. Get the screen / element size (element size is explained in the touch actions) /** * CODE THIS STEP */ // 2. Determine the x/y from/to position const from = { // Get the center of the horizontal axis x: '{DETERMINE-VALUE}', // Always start a few pixels above the bottom of the screen // otherwise you might open a system menu y: '{DETERMINE-VALUE}', }; const to = { // Get the center of the horizontal axis x: '{DETERMINE-VALUE}', // Stop at the top of the screen, or maybe a little bit below // the top y: '{DETERMINE-VALUE}', }; /** * CODE THIS STEP */ // 3. Execute the touch perform // 3a. The press which is the start position of your finger // 3b. The wait for the speed of the move to // 3c. The move which will be the end position of your finger // 3d. Now release it // For demo purpose driver.pause(5000); }); it('should be able to do a swipe with TouchActions', () => { // Prepare test by adding the first product to the cart and go to the cart $$('~test-ADD TO CART')[0].click(); // Open the cart $('~test-Cart').click(); $('~test-Cart Content').waitForDisplayed(); /** * CODE THIS STEP */ // 1. Get the size of the element const firstItem = $$('~test-Item')[0]; /** * CODE THIS STEP */ // 2. Determine X and Y position // We move our finger on the horizontal axis, this means we need to // have a starting X position and the Y position will stay the same. // We need to determine the startX and centerY position const startX = '{DETERMINE-VALUE}'; const centerY = '{DETERMINE-VALUE}'; /** * CODE THIS STEP */ // 3. Execute the touch action // We swipe over the horizontal axis which means the Y position // will always stay the same, but you can change it to create // different gestures for swiping // See https://github.com/jlipps/simple-wd-spec#perform-actions // for a clear explanation of all properties // 3a. Create the event // 3b. Move finger into start position // 3c. Finger comes down into contact with screen // 3d. Pause for a little bit // 3e. Finger moves to end position // We move our finger from the center of the element to the // starting position of the element // 3f. Finger lets up, off the screen // For demo purpose driver.pause(5000); }); it('should be able to scroll the easy way', () => { // 2. Android and iOS have their own implementation of executing a "simple" // scroll, so we ask the driver here if we are an Android or iOS device // Be aware that you need to have Appium 1.19.0 on your machine! if (driver.isAndroid) { // 2a. See http://appium.io/docs/en/writing-running-appium/android/android-mobile-gestures/#mobile-scrollGesture // for more information /** * CODE THIS STEP */ } else { // 2b. See http://appium.io/docs/en/writing-running-appium/ios/ios-xctest-mobile-gestures/index.html#mobile-scroll // for more information /** * CODE THIS STEP */ } // For demo purpose driver.pause(5000); }); it('should be able to swipe the easy way', () => { // Prepare test by adding the first product to the cart and go to the cart $$('~test-ADD TO CART')[0].click(); // Open the cart $('~test-Cart').click(); $('~test-Cart Content').waitForDisplayed(); // 1. Get the swag item we want to swipe const firstItemId = $$('~test-Item')[0].elementId; // 2. Android and iOS have their own implementation of executing a "simple" // swipe, so we ask the driver here if we are an Android or iOS device // Be aware that you need to have Appium 1.19.0 on your machine! if (driver.isAndroid) { // 2a. See http://appium.io/docs/en/writing-running-appium/android/android-mobile-gestures/#mobile-swipegesture // for more information /** * CODE THIS STEP */ } else { // 2b. See http://appium.io/docs/en/writing-running-appium/ios/ios-xctest-mobile-gestures/#mobile-swipe // for more information /** * CODE THIS STEP */ } // For demo purpose driver.pause(5000); }); });
GetStartedIos.cs (source from Sauce Labs Training C#)
DotNet NUnit iOS Example
Expand source
���using System; using NUnit.Framework; using NUnit.Framework.Interfaces; using OpenQA.Selenium; using OpenQA.Selenium.Appium; using OpenQA.Selenium.Appium.Enums; using OpenQA.Selenium.Appium.iOS; namespace Appium4.NUnit.Scripts.RealDevices.NativeApp.UP { [TestFixture] [Parallelizable] public class GetStartedIos { private static string HubUrl => "ondemand.us-west-1.saucelabs.com/wd/hub"; private IOSDriver<IOSElement> _driver; [Test] [Category("SimpleTest")] [Category("NativeApp")] public void ShouldOpenNativeIosApp() { var sauceUser = Environment.GetEnvironmentVariable("SAUCE_USERNAME", EnvironmentVariableTarget.User); var sauceAccessKey = Environment.GetEnvironmentVariable("SAUCE_ACCESS_KEY", EnvironmentVariableTarget.User); var uri = $"https://{sauceUser}:{sauceAccessKey}@{HubUrl}"; var capabilities = new AppiumOptions(); //We can run on any version of the platform as long as it's the correct device //Make sure to pick an Android or iOS device based on your app capabilities.AddAdditionalCapability(MobileCapabilityType.DeviceName, "iPhone 11 Pro Max"); capabilities.AddAdditionalCapability(MobileCapabilityType.PlatformName, "iOS"); capabilities.AddAdditionalCapability(MobileCapabilityType.Language, "en"); capabilities.AddAdditionalCapability("name", TestContext.CurrentContext.Test.Name); /* * You need to upload your own Native Mobile App to Sauce Storage! * https://wiki.saucelabs.com/display/DOCS/Uploading+your+Application+to+Sauce+Storage * You can use either storage:<app-id> or storage:filename= */ capabilities.AddAdditionalCapability("app", "storage:filename=iOS.RealDevice.SauceLabs.Mobile.Sample.app.2.7.0.ipa"); //60 seconds for the connection timeout _driver = new IOSDriver<IOSElement>(new Uri(uri), capabilities); var windowHeight = int.Parse(_driver.Manage().Window.Size.Height.ToString()); Assert.Greater(windowHeight, 0); } //Never forget to pass the test status to Sauce Labs [TearDown] public void Teardown() { if (_driver == null) return; var isTestPassed = TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Passed; ((IJavaScriptExecutor)_driver).ExecuteScript("sauce:job-result=" + (isTestPassed ? "passed" : "failed")); _driver.Quit(); } } }
iphone_config.txt (source from Sauce Labs Training Python)
Robot iOS Example config
Expand source
--variable platformName:iOS --variable deviceName:iPhone.* --variable privateDevicesOnly:False
resource.robot (source from Sauce Labs Training Python)
Robot iOS Example resource
Expand source
*** Settings *** Library AppiumLibrary *** Variables *** ${PLATFORM_NAME} %{platformName} ${DEVICE_NAME} %{deviceName} ${PRIVATE_DEVICES_ONLY} %{privateDevicesOnly} ${REMOTE_URL} ${DATA_CENTER} *** Keywords *** Start Session Open application ${REMOTE_URL} ... platformName=${PLATFORM_NAME} ... deviceName=${DEVICE_NAME} ... username=%{SAUCE_USERNAME} ... accessKey=%{SAUCE_ACCESS_KEY} ... privateDevicesOnly=${PRIVATE_DEVICES_ONLY} ... app=storage:filename=iOS.RealDevice.SauceLabs.Mobile.Sample.app.2.3.0.ipa ... name=${TEST_NAME} End Session Close all applications Login As Standard User Input text accessibility_id=test-Username standard_user Input text accessibility_id=test-Password secret_sauce Click element accessibility_id=test-LOGIN Login As Invalid User Input text accessibility_id=test-Username invalid Input text accessibility_id=test-Password invalid Click element accessibility_id=test-LOGIN
valid_login.robot (source from Sauce Labs Training Python)
Robot Example iOS test
Expand source
*** Settings *** Documentation A test suite with a single test for valid login. ... ... This test has a workflow that is created using keywords in ... the imported resource file. Resource resource.robot *** Test Cases *** Valid Login with Standard User Start Session Login As Standard User Page should contain element accessibility_id=test-PRODUCTS [Teardown] End Session
Coming Soon!
Overview
Content Tools
Activity
Tasks