Smart TV testing on BrowserStack App Automate
A guide to running your Appium tests on smart TV devices with BrowserStack App Automate.
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.ipa
file).
2. Upload your app
- If you do not have a
.apk
or.ipa
file and want to try out a test of smart TV , you can download and test our sample app for Android and our sample app for tvOS.
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.
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 theapp_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
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
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!