WebDriver Automation With Dart – Automating LinkedIn Post

WebDriver Automation With Dart – Automating LinkedIn Post

This article is a fun project that happened to lead me to create a very nice automation script using Dart. The WebDriver is an open-source package that is available for Dart. This article lists all the required steps to automate the LinkedIn ‘Post’ flow.

Motivation for LinkedIn Automation Using Dart

Before we jump in to the little side project, i need to explain what got me started to do this automation! The main reason being i make a lot of videos and the videos require ‘Social Sharing’. It gets really tedious to perform this repetitive task, and that’s why i made this script that will run as a standalone program performing the task for me.

Setting up the Project

Setting up the project is fairly simple, create a simple package(I have it named as dart-automation). Create a project with 2 files

  • main.dart – This is where the dart code is going to live
  • pubspec.yaml – This is where the dependency files are going to be provided.

Once the project setup is done, you have to include your first dependency(And the only dependency), which is the

webdriver: ^2.1.1

The pubspec.yaml looks like this,

name: dart_automation
dependencies:
    webdriver: ^2.1.1
Package structure
Package structure
Code Sample
Code Sample

WebDriver Package in Dart

What’s the purpose of the WebDriver package? Firstly, the package is a community maintained package, that is written over the ‘Selenium‘ toolkit. It’s sole purpose is to provide handles for both ChromeDriver and GeckoDriver to perform Web Automation Testing.

These are important for our project here because, the idea is to use this and create a simple automated flow of the ChromeDriver (LinkedIn.com) in this example and perform the ‘Post’ flow.

Building the LinkedIn Automation

Time to dive deep and understand what the entire Automation Flow is going to look like,

  • Open a instance of the ChromeDriver and ‘get’ the ‘www.linkedin.com’ URL
  • Once it opens, use the ‘Element’ Locators to find the ‘username’ and ‘password’ fields
  • Enter the values and login to the LinkedIn Account
  • Find the element locator for ‘share a post’ field and start entering the value you want to post
  • Find and click the element locator for ‘POST’

The code snippet given below is capable enough of doing this entire flow! Replace the username and password with a valid one to test it out on your local desktop

import 'dart:convert';
import 'dart:io';
import 'package:webdriver/sync_io.dart';

var chromeDriverProcess;

var driver;

Future startChromeDriverProcess() async {
  print('startChromeDriverProcess: starting ChromeDriverProcess');
  chromeDriverProcess = await Process.start(
      'chromedriver', ['--port=4444', '--url-base=wd/hub', '--verbose'],
          );

  await for (String browserOut in const LineSplitter()
      .bind(utf8.decoder.bind(chromeDriverProcess.stdout))) {
    if (browserOut.contains('Starting ChromeDriver')) {
      print('startChromeDriverProcess: ChromeDriverProcess succesfully started');
      print(browserOut);
      break;
    }
  }
}

Future _launchChrome() async {
  print('BrowserHandler._launchChrome: initializing ChromeDriver');

  
    driver = await createDriver(spec: WebDriverSpec.JsonWire); //this the point where the test gets stuck_
    print('BrowserHandler._launchChrome: ChromeDriver initialized');
    // await driver.get('https://www.google.com');
    print('BrowserHandler._launchChrome: loaded');
    return driver;
  
}
_openYoutube(driver) async{
driver.get('https://www.facebook.com');
sleep(Duration(seconds: 2));
// click the signin button and enter credentials
WebElement signin = driver.findElement(const By.cssSelector('paper-button[aria-label="Sign in"]'));
print(signin);
signin.click();

WebElement username = driver.findElement(const By.cssSelector('input[type="email"]'));
username.sendKeys("baradwaj.varadharajan@gmail.com");
WebElement next = driver.findElement(const By.id("identifierNext"));
print(next);
next.click();
sleep(Duration(seconds: 2));

WebElement password = driver.findElement(const By.cssSelector('input[type="password"]'));
password.sendKeys("**********");
WebElement next_button = driver.findElement(const By.id("passwordNext"));
print(next_button);
next_button.click();

}

_postOnFacebook(driver) async {
  print("Waitinf for facebook to load");
  await driver.get('https://www.facebook.com/androidsmonk');
  sleep(Duration(seconds: 2));
  // Click the input button and enter username and password
  WebElement username = await driver.findElement(const By.cssSelector('input[type="email"'));
  print(username);
  username.sendKeys("barathholmes@yahoo.com");
  
  WebElement password = await driver.findElement(const By.cssSelector('input[type="password'));
  password.sendKeys("********");

  WebElement login = driver.findElement(const By.cssSelector('input[aria-label="Log In"]'));
  login.click();

  WebElement writeAPost = driver.findElement(const By.cssSelector('text-area[aria-label="Write a post..."]'));
  writeAPost.sendKeys("This is a automated post");

}

_postOnLinkedIn() async{
  driver.get('https://www.linkedin.com/');
  sleep(Duration(seconds: 2));
  WebElement username = driver.findElement(const By.cssSelector('input[aria-label="Type your email or phone number"'));
  print(username);
  username.sendKeys("baradwaj.varadharajan@gmail.com");

  WebElement password = driver.findElement(const By.cssSelector('input[aria-label="Type your LinkedIn password"]'));
  password.sendKeys("Barath123");

 driver.findElement(const By.cssSelector('button[aria-label="i18n_sign-in"]')).click();
 
//  compose Message
driver.findElement(const By.cssSelector('li-icon[type="compose-icon"]')).click();
WebElement post = driver.findElement(const By.className('mentions-texteditor__content'));
post.sendKeys("TThis is going to be another automated post that works fine in the Hacking dart Part 2 video!");

driver.findElement(const By.cssSelector('button[data-control-name="share.post"]')).click();
}
void main() async {
  await startChromeDriverProcess();
  await _launchChrome();
  await _postOnLinkedIn();
  // await _postOnFacebook(driver);
}

LinkedIn Automation – Things to Remember

  • The entire Automation flow is based on the assumption that, you have ‘ChromeDriver’ installed and are using the ‘WebDriver’ package as suggested in the above section
  • There are additional methods for ‘Youtube’ and ‘Facebook’. These are really sporadic and are not going to work unless you have the ‘automation-flag’ turned off. More about this here.

In case you are interested to learn more about the ‘Automation with Dart’ story, find my video on the same below!

Leave a Comment