Search code examples
androidseleniumautomated-testsappiumselendroid

Appium Mobile Web test automation Android for Twitter


I was making a test automator using Appium on a selenium server for my Android device. The automator launches the Twitter's webapp does a login and posts a Tweet. However, the part I'm having difficulty with is that the automator doesn't use the already logged in account on my Chrome browser. Why do I have to login every time? Is it because the session refreshes? Is there a way to avoid this?

My code:

import java.net.MalformedURLException;  
import java.net.URL;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.MobileCapabilityType;

import org.eclipse.jetty.util.log.Log;
import org.openqa.selenium.By;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.BrowserType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class StartChrome
{
private String email="your_email";
private String password="your_password";
private WebDriver driver=null;
private int flag=0;

@BeforeTest
public void test1() throws MalformedURLException, InterruptedException{

// Create object of  DesiredCapabilities class and specify android platform
DesiredCapabilities capabilities=DesiredCapabilities.android();


// set the capability to execute test in chrome browser
 capabilities.setCapability(MobileCapabilityType.BROWSER_NAME,BrowserType.CHROME);

// set the capability to execute our test in Android Platform
   capabilities.setCapability(MobileCapabilityType.PLATFORM,Platform.ANDROID);

// we need to define platform name
  capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");

// Set the device name as well (you can give any name)
 capabilities.setCapability(MobileCapabilityType.DEVICE_NAME,"my phone");

 // set the android version as well 
   capabilities.setCapability(MobileCapabilityType.VERSION,"6.0.1");

 // Create object of URL class and specify the appium server address
 URL url= new URL("http://127.0.0.1:4727/wd/hub");

// Create object of  AndroidDriver class and pass the url and capability that we created
 WebDriver driver = new AndroidDriver(url, capabilities);

// Open url
  driver.get("http://www.twitter.com");

 // print the title
  System.out.println("Title "+driver.getTitle());
    try{
  driver.findElement(By.id("react-root"));      
    }catch(Exception e){
        driver.findElement(By.linkText("Log in")).click();
        Thread.sleep(3000);
        driver.findElement(By.name("session[username_or_email]")).sendKeys(email);
        driver.findElement(By.name("session[password]")).sendKeys(password);
        driver.findElement(By.id("signupbutton")).click();
        Thread.sleep(5000);
        driver.findElement(By.cssSelector("a[href*='/compose/tweet']")).click();    
        flag=1;
    }
    finally{
        if(flag==0){
            driver.findElement(By.cssSelector("a[href*='/compose/tweet']")).click();    
            }
    }
    driver.findElement(By.cssSelector("textarea[aria-label*='Tweet text']")).sendKeys("Test");;
    //driver.findElement(By.linkText("Tweet")).click();
    Thread.sleep(2000);
    driver.findElement(By.cssSelector("button[data-testid*='Button']")).click();


Thread.sleep(2000);
driver.quit();

}

Any help is much appreciated! :)


Solution

  • Twitter session handles by setting client side token cookies. This token is hashcode composed commonly from your credentials and browser fingerprinting. Since WebDriver starts every time 'clear' browser, without cookies, of course - server doesn't recognize you and ask for authentication.

    Solutions:

    • Just accept this. Login every time. It looks as sane test-case. I would recommend this decision.
    • Save token cookies _twitter_sess.
      Cookie ck = new Cookie("_twitter_sess", "your_authorised_session_id");
      driver.manage().addCookie(ck);
    

    Risks: 1) This session cookie has expiration date. You will have to copypaste new your_authorised_session_id every morning. 2) It's possible that Twitter has tricky security system and they check browser fingerprint

    • Use your existing Chrome Profile, it means your browser 'non clear one' that contains your history, your cookies. So you have to login to twitter manually right before running tests and it will persist.
    ChromeOptions options = new ChromeOptions();
    options.addArguments("user-data-dir=C:/Users/user_name<your_path_to_installed_chrome_in_mob_phone_in_your case>/AppData/Local/Google/Chrome/UserData");
    driver = new ChromeDriver(options);