We often come across scenarios where we have to upload a file/image while testing an application. There are multiple ways to upload a file which we have seen using Selenium like using sendkeys() or using JavaScript() or Robot Class.
Now, I have seen people asking for 'How to upload/attach file using Appium' .
Unfortunately, there is no way like Selenium SendKeys() or javascript options to work for file upload in mobile application using Appium. We literally have to do everything via UI - as we manually do like click upload button, open image selection, select image and etc.
The only thing that Appium can assist with is to upload files to device, so your device can be cleaned and populated only during the test automation using pushFile method. We will discuss below on this with example.
When we try to upload using sendKeys() with file path from the device itself, webdriver will throw below exception:
org.openqa.selenium.WebDriverException: An unknown server-side error occurred while processing the command. Original error: unknown error: path is not absolute: /sdcard/download/test.pdf
In this post, we’ll discuss on uploading a file from Mobile device to a web application (chromer browser).
When automating a file upload, after clicking on 'Upload' button, it will prompt you with a dialog box that is just out of reach for Appium web. Like Selenium, In Appium also, we can't perform actions once the view is changed from 'Chrome' web to 'NATIVE' app.
To perform operations, we have to switch the context from Web view to Native view to attach a file using Appium. Let’s first try to understand 'How to Switch from Chrome to Native app' using Appium with example.
"One of the core principles of Appium is that you shouldn't have to change your app to test it. In line with that methodology, it is possible to test hybrid apps the same way you can with Selenium for web apps".
In order to let Appium know whether you want to automate the native aspects of the app or the web views, we have to set the 'context' being automated.
Syntax : - To move to Native view context
driver.context("NATIVE_APP");
Syntax : - To move to Chrome browser context
driver.context("CHROMIUM");
If you are moving into a web view context it will involve attempting to connect to that web view and in the same way, If you are moving into a native context it will involve attempting to connect to Native view.
Code Example to Upload File using Appium
Before we step forward, it’s important to understand that this is a simple example using Android Emulator version 10. Please check that the locators may differ on your device based on the version selected.
Please find below steps :
Step 1: Open URL
Step 2: Click on upload button
Step 3: Switch to Context (NATIVE_APP)
Step 4: Push file from your locale machine to device
Step 5: Click on 'Allow' - permission
Step 6: Click on files
Step 7: Select file to upload (Should see the file we pushed to device under downloads)
Step 8: Switch to Context (CHROMIUM)
Step 9: Click on Upload button on browser
Step 10: Assertion to validate file/image uploaded successfully using Appium
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.MobileCapabilityType;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.*;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Set;
public class AppiumTest {
AndroidDriver driver;
WebDriverWait wait;
String AppURL = "http://cgi-lib.berkeley.edu/ex/fup.html";
@BeforeTest
public void setup() throws MalformedURLException {
// Create an object for Desired Capabilities
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "10.0");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Pixel");
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UIAutomator2");
capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Chrome");
// Initialize the driver object with the URL to Appium Server and
// passing the capabilities
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
wait = new WebDriverWait(driver, 5);
driver.setFileDetector(new LocalFileDetector());
}
@Test
public void testSearchAppium() throws IOException {
//Navigate to app url
driver.get(AppURL);
//Click on upload button
By uploadBtn = By.name("upfile");
wait.until(ExpectedConditions.visibilityOfElementLocated(uploadBtn));
driver.findElement(uploadBtn).click();
//Push file to device
driver.pushFile("/sdcard/download/test.pdf", new File("C:\\Users\\HarryDev\\Downloads\\cmp_html_page_size.pdf"));
//Switch to Native_App
Set<String> contextNames = driver.getContextHandles();
for (String strContextName : contextNames) {
if (strContextName.contains("NATIVE_APP")) {
driver.context("NATIVE_APP");
break;
}
}
//Click on 'Allow' - permission
By elementView = By.id("com.android.permissioncontroller:id/permission_allow_button");
wait.until(ExpectedConditions.visibilityOfElementLocated(elementView));
driver.findElement(elementView).click();
//Click on files
By eleFile = By.xpath("//*[@text="Files"]");
wait.until(ExpectedConditions.visibilityOfElementLocated(eleFile));
driver.findElement(eleFile).click();
//select pdf file from downloads (location of pdf file)
By eleDoc = By.id("com.android.documentsui:id/thumbnail");
wait.until(ExpectedConditions.visibilityOfElementLocated(eleDoc));
driver.findElement(eleDoc).click();
//Switch to Chrome browser
Set<String> contextNames1 = driver.getContextHandles();
for (String strContextName : contextNames1) {
if (strContextName.contains("CHROMIUM")) {
driver.context("CHROMIUM");
break;
}
}
//Click on submit button
WebElement btnElement = driver.findElement(By.cssSelector("input[type=submit]"));
wait.until(ExpectedConditions.visibilityOf(btnElement));
btnElement.click();
//Add a simple assertion
By nextPageHeader = By.cssSelector("h1");
wait.until(ExpectedConditions.visibilityOfElementLocated(nextPageHeader));
Assert.assertTrue(driver.findElement(nextPageHeader).getText().equals("File Upload Results"));
}
@AfterTest
public void tearDown() {
if(driver !=null)
driver.quit();
}
}
On executing the above code, the file will be uploaded successfully and test should PASS.
If you want to add a file manually to the emulated device, you can drag the file onto the emulator screen. The file will be placed in the /sdcard/Download/ directory. You can also view the file from Android Studio using the Device File Explorer, or find it from the device using the Downloads or Files app, depending on the device version.
If you have any questions/suggesstions, please add a comment.
- ‹ Top 10 Codeless Testing Tools in 2020 You’d Better Know
- Migrating from Selenium to Katalon Studio | A Progress in Codeless Test Automation ›
Comments
test case
How to push a file from local machine to emulator and check if the file name is same as the file name in the local machine
Add new comment