The Sauce Labs Cookbook

Sauce Headless

Front End Performance Testing

Insights

External Resources

More Info


Page tree
Skip to end of metadata
Go to start of metadata

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:

Java11 Junit4 iOS Example
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());
    }
}

WebdriverIO Example config
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;

WebdriverIO Example spec
//
// ==================================================================
// 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);
  });
});

DotNet NUnit iOS Example
���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();
        }
    }
}

Robot iOS Example config
--variable platformName:iOS
--variable deviceName:iPhone.*
--variable privateDevicesOnly:False 

Robot iOS Example resource
*** 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

Robot Example iOS test
*** 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!