Cannot get application documents using'pullFile' on iOS

Hi,

I’m trying to use the ‘pullFile’ command on iOS to get some files in the ‘Documents’ folder of my app. According to the documentation, we can use “/AppName.app” in the path to have it automatically replaced by the real path but this is not working so far:

driver.pullFile("/AppName.app/Documents/Log-2016-05-04.txt");

result:
An unknown server-side error occurred while processing the command. Original error: ENOENT, open '/Users/fdubuisson/Library/Developer/CoreSimulator/Devices/9A2BD86D-B535-4CD9-A3D8-7816EF5AA676/data/AppName.app/Documents/Log-2016-05-04.txt' (WARNING: The server did not provide any stacktrace information)

appium daemon logs:
[debug] [iOS] Executing iOS command ‘pullFile’
[debug] [iOS] Pulling /AppName.app/Documents/Log-2016-05-04.txt from sim
[debug] [iOS] We want a sim-relative file
[debug] [iOS] Attempting to read /Users/fdubuisson/Library/Developer/CoreSimulator/Devices/9A2BD86D-B535-4CD9-A3D8-7816EF5AA676/data/AppName.app/Documents/Log-2016-05-04.txt
[MJSONWP] Encountered internal error running command: Error: ENOENT, open ‘/Users/fdubuisson/Library/Developer/CoreSimulator/Devices/9A2BD86D-B535-4CD9-A3D8-7816EF5AA676/data/AppName.app/Documents/Log-2016-05-04.txt’
at Error (native)

Did I misunderstand the documentation ? Did someone was able to use this feature ?

Thank you !

@fdubuisson

Just with the intent of help, I am sharing something which I used for Android and it worked well

I have used this API for android, I am not sure about the filesystem of iOS Simulator or Real iPhone

  1. First thing are u able to manually navigate to this file using cmd
    some thing like
    cd /AppName.app/Documents/
    ls Log-2016-05-04.txt ===> does this command says file exists in this folder
    so make sure path should be correct on real device as well if u use simulator

  2. driver.pullFile accepts File path as string

  3. driver.pullFile returns File in form of byte array, so after pulling file we need to write that byte array to a text file or any other file what ever we pulled

package Appium;

import java.awt.image.BufferedImage;
import io.appium.java_client.android.AndroidDriver;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;

import javax.imageio.ImageIO;
import org.apache.commons.codec.binary.Base64;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

@Test
public class pushFileTest {

	public static AndroidDriver<WebElement> _driver;
	
	@BeforeClass
	public void setUpAppium() throws InterruptedException, IOException {

		System.out.println("**************** setUP Starts ***************");
				
		DesiredCapabilities cap = new DesiredCapabilities();   
		cap.setCapability(CapabilityType.BROWSER_NAME,"");
		
	
		/* Kitkat 4.4.4 */
		cap.setCapability("platformVersion","4.4.2");
		cap.setCapability("platformName","Android");
		cap.setCapability("deviceName","ZX1B32HNBD");
		cap.setCapability("appPackage","io.appium.android.apis");
		cap.setCapability("appActivity","ApiDemos");
		//System.out.println("Before calling appium");
		_driver = new AndroidDriver<WebElement>(new URL("http://127.0.0.1:4725/wd/hub"), cap);
		//System.out.println("After calling appium");
	}
	
	@Test		
	public void pullImageFileFromMobileSDCardTest() throws IOException {
		
		byte[] returnData = _driver.pullFile("/storage/sdcard1/PAN_DIR/IMG_20140828_072840.jpg");
		//System.out.println("Base 64 Converted String received from mobile :: " + returnData);
		BufferedImage image=ImageIO.read(new ByteArrayInputStream(returnData));
		ImageIO.write(image, "jpg", new File("C:\\eclipse","snap.jpg"));
	}
	
	@Test
	public void pullTextFileFromMobileSDCardTest() throws IOException {
	 	byte[] returnData = _driver.pullFile("/storage/sdcard1/mili_log.txt");
		//System.out.println(" Printing Text of File received from mobile :: " + new String(Base64.decodeBase64(returnData)));
		File fs = new File("C:\\eclipse\\MobileFile.txt");
		FileOutputStream fos = new FileOutputStream(fs);
        fos.write(returnData);
        fos.flush();
        fos.close();
	}	
	
	  @Test
	  public void pushImageFileFromMobileTest() throws IOException {
		  File fi = new File("C:\\eclipse\\img1.jpg");
		  byte[] fileContent = Files.readAllBytes(fi.toPath());
        _driver.pushFile("/storage/sdcard1/PAN_DIR", fileContent);          
	  }
	  
	  @Test
		public void pushTextFileFromMobileTest() throws IOException {
			  File fi = new File("C:\\eclipse\\MobileFile.txt");
			  byte[] data = Files.readAllBytes(fi.toPath());
			System.out.println("Base 64 Converted String sent to mobile :: " + data);
			_driver.pushFile("/storage/sdcard1/PAN_DIR/appium.txt",data);
		}
	  
	  public void pullVideoFileFromMobileSDCardTest() throws IOException {
			
			byte[] returnData = _driver.pullFile("/storage/sdcard1/PAN_DIR/VideoIconfile.mp4");
			//System.out.println(" Printing Text of File received from mobile :: " + new String(Base64.decodeBase64(returnData)));
			//File fs = new File("C:\\eclipse\\video.mp4");
			FileOutputStream fos = new FileOutputStream("C:\\eclipse\\video.mp4");
		    fos.write(returnData);
	        fos.flush();
	        fos.close();
			}
	  
		@AfterTest(alwaysRun= true)
		public void tearDown(){
	   		if (_driver!= null ) 
	   			_driver.quit();
	   		System.out.println("tearDown() :: driver.quit() executed");
		}

}

Thanks for your help.

What I found is that with the current ‘pullFile’ command, on iOS, we can either access the simulator ‘root’ filesystem or the application bundle. But we can’t directly access the application data created during its execution (documents, logs, …).
And this is this last path that was interesting for me :slight_smile: