Skip to main content
No Result Found

Smart TV testing on BrowserStack App Automate

A guide to running your Appium tests on smart TV devices with BrowserStack App Automate.

Important: BrowserStack currently supports an alpha version of smart TV testing, and thus, it is not available to all users yet. If you want to get access to smart TV testing, contact support and request access to the Smart TV alpha release.

App Automate lets you test your apps on smart TV. We currently support testing apps on:

  • Amazon Fire TV Stick 4K (Android v7.1)
  • Nvidia Shield TV Pro 2019 (Android v11.0)
  • Apple TV 4k (tvOS v16.3)

1. Setup your environment

  • Access to the alpha version of smart TV testing
  • You will need a BrowserStack username and access key. To obtain your access credentials, sign up for a free trial or purchase a plan.
  • Access to a smart TV app (.apk or .ipafile).

2. Upload your app

Note:

Upload your app (.apk/.ipa) file to BrowserStack servers using our REST API request as follows:

curl -u "YOUR_USERNAME:YOUR_ACCESS_KEY" \
-X POST "https://api-cloud.browserstack.com/app-automate/upload" \
-F "file=@/path/to/app/file"

# Ensure that `@` symbol is prepended to the file path in the request.
curl -u "YOUR_USERNAME:YOUR_ACCESS_KEY" ^
-X POST "https://api-cloud.browserstack.com/app-automate/upload" ^
-F "file=@/path/to/app/file"

# Ensure that `@` symbol is prepended to the file path in the request.

A sample response for the request is as follows:

{
    "app_url":"bs://j3c874f21852ba57957a3fdc33f47514288c4ba4"
}

Note the value of app_url returned in the response to the REST API request. This value will be used later to specify the application under test for your test execution.

Important: App upload might take a few seconds to about a minute depending on the size of your app. Do not interrupt the cURL command until you get the response in your command-line/terminal.

3. Configure and run your test

In this step, you will learn how to configure your Appium test script using desired capabilities to test remotely on BrowserStack’s real device cloud along with a sample test script.

Update your test script with the following changes:

  • Set the app capability to the app_url of the app you uploaded
  • Set device capability to either of the following two options:
    • Amazon Fire TV Stick 4K - run tests on Fire TV
    • Nvidia Shield TV Pro 2019 - run tests on Nvidia Shield TV
    • Apple TV 4k - run tests on Apple TV 4k
  • Initialize an Appium driver using a remote BrowserStack URL along with your BrowserStack credentials as follows:
      https://YOUR_USERNAME:YOUR_ACCESS_KEY@hub.browserstack.com/wd/hub
    

Sample test script

The following sample Ruby test script includes device capabilities to run a test on the Fire TV or an Apple TV app.

Fire TV & Nvidia Shield

import io.appium.java_client.AppiumBy;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.nativekey.AndroidKey;
import io.appium.java_client.android.nativekey.KeyEvent;
import io.appium.java_client.android.options.UiAutomator2Options;
import org.openqa.selenium.By;
import org.openqa.selenium.MutableCapabilities;
import io.appium.java_client.android.AndroidDriver;
import java.net.URL;
import static org.openqa.selenium.By.*;

public class SmartTVTest {

    public void testSmartTV() throws Exception {
        AndroidDriver driver;

        MutableCapabilities caps = new UiAutomator2Options();
        caps.setCapability("build", "Smart TV Test");
        caps.setCapability("deviceName", "Amazon Fire TV Stick 4K");
        caps.setCapability("osVersion", "7.1");
        caps.setCapability("appium:browserstack.dedicatedDevice", true);
        caps.setCapability("app", APP_ID);

        driver = new AndroidDriver(new URL("https://" +
                BROWSERSTACK_USER + ":" + BROWSERSTACK_ACCESS_KEY +
                "@hub.browserstack.com/wd/hub"), caps);


        Thread.sleep(5000);
        driver.pressKey(new KeyEvent().withKey(AndroidKey.DPAD_CENTER));
        Thread.sleep(5000);
        driver.pressKey(new KeyEvent().withKey(AndroidKey.DPAD_LEFT));
        Thread.sleep(5000);
        driver.pressKey(new KeyEvent().withKey(AndroidKey.DPAD_LEFT));
        Thread.sleep(5000);
        driver.pressKey(new KeyEvent().withKey(AndroidKey.DPAD_RIGHT));
        Thread.sleep(5000);
        driver.pressKey(new KeyEvent().withKey(AndroidKey.DPAD_RIGHT));
        Thread.sleep(5000);
        driver.pressKey(new KeyEvent().withKey(AndroidKey.DPAD_RIGHT));
        Thread.sleep(5000);
        driver.pressKey(new KeyEvent().withKey(AndroidKey.DPAD_RIGHT));
        Thread.sleep(5000);
        driver.pressKey(new KeyEvent().withKey(AndroidKey.DPAD_CENTER));
        Thread.sleep(5000);
        driver.pressKey(new KeyEvent().withKey(AndroidKey.DPAD_RIGHT));

        Thread.sleep(5000);
        driver.pressKey(new KeyEvent().withKey(AndroidKey.DPAD_CENTER));
        Thread.sleep(5000);
        driver.pressKey(new KeyEvent().withKey(AndroidKey.DPAD_CENTER));
        Thread.sleep(10000);
        driver.pressKey(new KeyEvent().withKey(AndroidKey.MEDIA_PLAY_PAUSE));

        driver.quit();
    }
}

require 'rubygems'
require 'appium_lib'

username = 'YOUR_USERNAME'
access_key = 'YOUR_ACCESS_KEY'

desired_caps = {
    'build': 'Ruby Appium Sample',
    'device': 'Amazon Fire TV Stick 4K',
    'osVersion': '7.1',
    'browserstack.debug': 'true',
    'app': '<app_hashed_id>'
}

appium_driver = Appium::Driver.new({
    'caps' => desired_caps,
    'appium_lib' => {
        :server_url => "https://#{username}:#{access_key}@hub-cloud.browserstack.com/wd/hub"
    }}, true)
driver = appium_driver.start_driver

sleep 5
driver.press_keycode(20) # DPAD_DOWN
driver.press_keycode(22) # DPAD_RIGHT

video_element = driver.find_element(:xpath, "//android.widget.FrameLayout[@focused = 'true']")
video_name = video_element.attribute('content-desc')
puts "Selected Video Name: #{video_name}"

driver.press_keycode(23) # DPAD_CENTER
sleep(5)
driver.press_keycode(85) # MEDIA_PLAY_PAUSE
sleep(3)
driver.press_keycode(85) # MEDIA_PLAY_PAUSE
sleep(3)
driver.press_keycode(89) # MEDIA_REWIND
sleep(3)
driver.press_keycode(4) # BACK

focussed_element = driver.find_element(:xpath, "//android.widget.FrameLayout[@focused = 'true']")
focussed_video_name = focussed_element.attribute('content-desc')

if focussed_video_name == video_name
  puts "Video played - Test passed"
else
  puts "Video Could not be played - Test Failed"
end

driver.quit
const webdriverio = require('webdriverio');

const opts = {
  port: 4723,
  capabilities: {
    platformName: 'Android',
    platformVersion: '7.1',
    deviceName: 'Amazon Fire TV Stick 4K',
    app: '<app_hashed_id>',
    'browserstack.debug': 'true',
  },
  path: '/wd/hub',
  user: 'YOUR_USERNAME',
  key: 'YOUR_ACCESS_KEY',
};

(async () => {
  const client = await webdriverio.remote(opts);

  await client.pause(5000);
  await client.pressKeyCode(20); // DPAD_DOWN
  await client.pressKeyCode(22); // DPAD_RIGHT

  const videoElement = await client.$(
    '//android.widget.FrameLayout[@focused = "true"]',
  );
  const videoName = await videoElement.getAttribute('content-desc');
  console.log(`Selected Video Name: ${videoName}`);

  await client.pressKeyCode(23); // DPAD_CENTER
  await client.pause(5000);
  await client.pressKeyCode(85); // MEDIA_PLAY_PAUSE
  await client.pause(3000);
  await client.pressKeyCode(85); // MEDIA_PLAY_PAUSE
  await client.pause(3000);
  await client.pressKeyCode(89); // MEDIA_REWIND
  await client.pause(3000);
  await client.pressKeyCode(4); // BACK

  const focussedElement = await client.$(
    '//android.widget.FrameLayout[@focused = "true"]',
  );
  const focussedVideoName = await focussedElement.getAttribute('content-desc');
  if (focussedVideoName === videoName) {
    console.log('Video played - Test passed');
  } else {
    console.log('Video Could not be played - Test Failed');
  }

  await client.deleteSession();
})();

Apple TV

Important: Appium 2.0 is the default and the only version supported by App Automate on tvOS, which comes with W3C capabilities.
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.ios.IOSElement;
import io.appium.java_client.remote.MobileCapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.ios.IOSDriver;

import java.net.URL;
import java.util.concurrent.TimeUnit;

import java.util.HashMap;

public class TVOSTest {

    public static String USERNAME = "<your-username>";
    public static String ACCESS_KEY = "<your-access-key>";

    public static void main(String[] args) throws Exception {
    DesiredCapabilities capabilities = new DesiredCapabilities();
    HashMap<String, Object> browserstackOptions = new HashMap<String, Object>();
    browserstackOptions.put("projectName" , "TVOS-PROJECT");
    browserstackOptions.put("buildName" , "TVOS-BUILD");
    browserstackOptions.put("sessionName" , "TVOS-SESSION");
    browserstackOptions.put("networkLogs" , true);
    capabilities.setCapability("bstack:options" , browserstackOptions);
    capabilities.setCapability("platformName" , "tvOS");
    capabilities.setCapability("platformVersion" , "16.3");
    capabilities.setCapability("deviceName" , "Apple TV 4K");
    capabilities.setCapability(MobileCapabilityType.APP , "<enter app url here>");
    capabilities.setCapability("automationName" , "XCUITest");
        
    IOSDriver driver = new IOSDriver(new URL("https://" + USERNAME + ":" + ACCESS_KEY +
            "@hub-cloud.browserstack.com/wd/hub"), capabilities);

    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
    System.out.println(driver.getPageSource());
    driver.getScreenshotAs(OutputType.FILE);
    driver.quit();
    }
}
require 'rubygems'
require 'appium_lib'
require 'selenium-webdriver'
# Use Ruby Client version v9.8.1 or above

username = 'YOUR_USERNAME'
access_key = 'YOUR_ACCESS_KEY'

caps = {
	"platformName" => "tvos",
	"platformVersion" => "16.3",
	"deviceName" => "Apple TV 4K",
    "app" => "<enter app url here>", 
    "automationName" => "xcuitest",
	'bstack:options' => {
		"networkLogs" => "true",
		"projectName" => "TVOS-PROJECT",
		"buildName" => "TVOS-BUILD",
		"sessionName" => "TVOS-SESSION",
	},
}


appium_driver = Appium::Driver.new({
	'caps' => caps,
	'appium_lib' => {
		:server_url => "https://#{username}:#{access_key}@hub-cloud.browserstack.com/wd/hub",
	}}, true)
driver = appium_driver.start_driver
wait = Selenium::WebDriver::Wait.new(:timeout => 30)

driver.page_source
driver.execute_script 'mobile: pressButton', { name: 'Down' }
driver.execute_script 'mobile: pressButton', { name: 'Down' }
driver.execute_script 'mobile: pressButton', { name: 'Left' }
driver.execute_script 'mobile: pressButton', { name: 'Left' }
driver.execute_script 'mobile: pressButton', { name: 'Select' }
sleep(5)
playButton = driver.find_element(:xpath, '//XCUIElementTypeButton[@name="Play"]')
puts playButton.text
playButton.click()
sleep(10)
driver.quit
const webdriver = require('selenium-webdriver');
const { Builder } = webdriver;

const username = 'YOUR_USERNAME';
const accessKey = 'YOUR_ACCESS_KEY';

const capabilities = {
  'platformName': 'tvos',
  'platformVersion': '16.3',
  'deviceName': 'Apple TV 4K',
  'app': '<enter app url here>',
  'automationName': 'xcuitest',
  'bstack:options': {
    'networkLogs': 'true',
    'projectName': 'TVOS-PROJECT',
    'buildName': 'TVOS-BUILD',
    'sessionName': 'TVOS-SESSION'
  }
};

const driver = new Builder()
  .usingServer(`https://${username}:${accessKey}@hub-cloud.browserstack.com/wd/hub`)
  .withCapabilities(capabilities)
  .build();

driver.getPageSource();
driver.executeScript('mobile: pressButton', { name: 'Down' });
driver.executeScript('mobile: pressButton', { name: 'Down' });
driver.executeScript('mobile: pressButton', { name: 'Left' });
driver.executeScript('mobile: pressButton', { name: 'Left' });
driver.executeScript('mobile: pressButton', { name: 'Select' });
driver.sleep(5000);
const playButton = driver.findElement(webdriver.By.xpath('//XCUIElementTypeButton[@name="Play"]'));
playButton.getText().then(text => {
  console.log(text);
  playButton.click();
  driver.sleep(10000);
  driver.quit();
});

4. View test execution results

After you start the test execution, visit your App Automate dashboard to view your test results.

You can drill down into the details of a specific test session to view its execution details and debugging information such as video recording, screenshots and appium logs.

You can also use API requests to view test results.

Need some help?

If you have any queries, contact support.

We're sorry to hear that. Please share your feedback so we can do better

Contact our Support team for immediate help while we work on improving our docs.

We're continuously improving our docs. We'd love to know what you liked





Thank you for your valuable feedback

Is this page helping you?

Yes
No

We're sorry to hear that. Please share your feedback so we can do better

Contact our Support team for immediate help while we work on improving our docs.

We're continuously improving our docs. We'd love to know what you liked





Thank you for your valuable feedback!

Talk to an Expert
Download Copy Check Circle