Export Python automation results to DataDog

  • The following Python script helps you to update the automation results right after the execution on exit
from datadog import initialize, api
import time, os, glob, json

print os.environ['API_KEY']

options = {
  'api_key': os.environ['API_KEY']


stats = json.load('./stats.json')

api.Metric.send(metric="qa.baseline.desktop.passed", points=stats['passed'], tags=["country:us")
api.Metric.send(metric="qa.baseline.desktop.failed", points=stats['failed'], tags=["country:us")
api.Metric.send(metric="qa.baseline.desktop.skipped", points=stats['skipped'], tags=["country:us")
  • Import the following Dashboard json with the basic settings required
  • Thats it!

Get appActivity and appPackage name from an unknown apk file

Method #1

  • Open Android Emulator
  • Copy and paste the apk file inside platform-tools folder
  • If you’ve installed SDK through ‘Android Studio’ in MAC, here is the location where you need to copy the .apk file
  • Open terminal and install your apk file in emulator
adb install app.apk
  • Finally obtain the appActivity and appPackage names
adb shell "dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'"

Method #2

  • Copy and paste the .apk file inside build-tools folder
  • Open terminal and run
./aapt dump badging app.apk
  • Observe the appPackage name and appActivity name separately

Linux cmds to troubleshoot DNS server


Troubleshoot DNS related issues

# get ip address of the host name
nslookup www.google.com

# get dns server name

# get mail server name
nslookup -querytype=MX www.google.com

$ nslookup
> set type=MX
> www.google.com

# get name server name
nslookup -querytype=NS www.google.com

$ nslookup
> set type=NS
> www.google.com

# switch default local Dserver to another server
$ nslookup
> server
> www.google.com

# switch back to default type
nslookup -querytype=A www.google.com

$ nslookup
> set type=A
> www.google.com


dig is the short form for Domain Information Groper; it is also used for troubleshooting DNS related issues

dig www.prashanthsams.com

# dig in short
dig www.prashanthsams.com +short
# debug in detail
dig +trace www.prashanthsams.com

Useful Linux Commands


Downloads a single file/folder or an entire site in a single cmd

# download entire html including images
wget -E -H -k -p https://www.google.com

# continue download from the middle
wget -c http:///.zip

# download in background
wget -b http:///.zip

# download entire website and its contents including landing pages
wget --mirror -p --convert-links -P ./folder http://www.google.com


Download multiple files through URL/links

# -o is for output and google.html is the output file & format
curl -o google.html https://www.google.com

# -# shows the progress
curl -# -o google.com https://www.google.com

# -k ignores the ssl certificate shows the progress
curl -k -o google.com https://www.google.com


Individual 7 (rwx/4+2+1) is a combination of permissions 4, 2, and 1; where, 4 – read, 2 – write, and 1 – execute

# check if the file(s) have read/write access
ls -la
ls -l 

# give read, write, and execute access to user, group, and others
chmod 777 
chmod a=rwx 

# give read, write, and execute access to all the files under a folder recursively
chmod -R 777 

# check if the files have read/write access
chmod u=rw 
chmod 500 
chmod g=rw 
chmod 050 
chmod o=rw 
chmod 005 


UID helps you switch between users

# list users with uid
cat /etc/passwd

# lists users 
dscl . -list /Users

# list users with uid
dscl . -list /Users UniqueID 

# get specific user id
dscl . -read /Users/prashanthrajjapa UniqueID


Global regular expression parser/print

# list all the matching files with text
ls * | grep 

# print the lines containing given text
grep --color  

# print the lines containing given text with line number
grep --color -n  

# print the lines containing with text from all the matching files
grep --color  *

# ignore case-sensitive
grep --color -i  

# search in all the sub directories recursively
grep --color -i -r  

# match any character in the middle using .*
grep --color  *


To know the number of word counts, lines, and characters in a file

# array 1 represents total number of lines
# array 2 represents total number of words
# array 3 represents total number of characters
wc < 

wc  -l
wc  -w
wc  -c


To view the status of the running processes

# lists all the running process with PID number
ps -A
ps -A | less

# BSD syntax to list all process with full details (owner, %MEM, start time, PID, etc.,)
ps axu
ps aux
ps axu | grep firefox

# check specific process run
ps -A | grep firefox

# check process start time
ps -ef | grep firefox
ps -ef | grep firefox | less


To kill the running process

# kill a process using process ID

# kill a process using name
pkill firefox

# force kill a process using name
killall -9 
(e.g., killall -9 chromedriver)


Set pseudo path for the existing one

# create symlink
ln -s  
(e.g., ln -s /Applications/Firefox.app/ firefox)

# create/update symlink
ln -sf  


Print current terminal source

# create symlink


Troubleshoot CPU memory usage

# check instant cpu memory usage live
top -F -R -o cpu

# check instant cpu memory usage live
top -o rsize


Advanced version of top; it has to installed externally and not comes by default

# check instant cpu memory usage live
sudo apt-get install htop


Helps you write logic in the cmd line and play with text

# print whole line 
ls -la | awk '{print $0}'

# print first field
ls -la | awk '{print $1}'
ls -l . | grep "^-" | awk '{print $1}'


Simplify your work by getting line count, duplicates and uniqueness from a file

# prints all the unique lines in a file
uniq -u your_text_file.format

# prints all the duplicate lines in a file
uniq -u your_text_file.format

# prints all the lines with duplicate counts in a file 
uniq -c your_text_file.format


Zip and unzip files

# compress a file 
compress file_name.format

# compress a file and print percentage reduction in size
compress -v file_name.format

# uncompress a file
uncompress file_name.format.Z

# uncompress a file and print percentage reduction in size
uncompress -v file_name.format.Z


Print file size

# readable format to see the size of file
ls -lh file_name.format

# alternate way to see the file size
du -sh file_name.format


Locate directory(ies) and it’s files in the local machine

find ~/ directory_name 

DB Connect

Command line DB conenction

# mysql db connect
mysql -u username -ppassword -h hostname
mysql> show databases;
mysql> use dbname;
mysql> show tables;

# mysql db connect with port and dbname
mysql -u username -ppassword -h hostname -P port -D dbname

PS1 – Primary Prompt

Run set of cmds on launching terminal/cmd prompt. PS1 is the primary cmd prompt, PS2 is the secondary cmd prompt, and PS3 is the least used cmd prompt.

# ps1 to change the terminal color 
export PS1="\e[0;32m\e[6m\u@\h \w> \e[m "
export PS1="\e[0;32m\e[1m\u@\h \w> \e[m "
export PS1="\e[0;36m\e[4m\u@\h \w> \e[m "
export PS1="\e[7;32m\e[1m\u@\h \w> \e[m "
export PS1="\e[5;32m\e[1m\u@\h \w> \e[m "
export PS1="\e[0;32m\e[1m\u@\h \w> \e[5m "
export PS1="\e[1;32m\e[1m\u@\h \w> \e[0m "
more details..
  • To make the above cmds effective, try copy & paste inside bash_profile
# set as environment variable
sudo vi ~/.bash_profile
export PS1="\e[1;32m\e[1m\u@\h \w> \e[0m "

Ruby Database cleaner (MySQL)

Database cleaner helps you clean database for tests

  • Install and config database_cleaner


gem 'database_cleaner'
gem 'sequel'


require 'database_cleaner'
require 'sequel'
  • DB connection through database_cleaner
connection = Sequel.connect("mysql2://username:password@hostname:port/db_name")
DatabaseCleaner[:sequel].db = connection
  • Alternate option for DB connect
DatabaseCleaner[:sequel, {:connection => Sequel.connect('mysql2://username:password@hostname:port/db_name')}]
  • Check if the connection is ready
  • Set transaction as the strategy; however, this works only if the table doesn’t have foreign key constraints
DatabaseCleaner.strategy = :transaction
<dirty the db>
  • To clean the complete table, clean the db with truncation
  • To ignore foreign key constraints,
connection.run('SET FOREIGN_KEY_CHECKS=0;')
connection.run('SET FOREIGN_KEY_CHECKS=1;')




Handle Basic authentication in Selenium for Chrome browser

Chrome extension

Create a simple chrome extension with custom username and password defined in it.

  • Create a .js file, background.js with the custom username and password
var username = "your_user";
var password = "your_pass";
var retry = 3;

  function handler(details) {
    if (--retry < 0)
      return {cancel: true};
    return {authCredentials: {username: username, password: password}};
  {urls: ["<all_urls>"]},

[Text in red has to be customized specific to the project]

  • Create a .json file, manifest.json as shown below
  "manifest_version": 2,
  "name": "Authentication for ...",
  "version": "1.0.0",
  "permissions": ["<all_urls>", "webRequest", "webRequestBlocking"],
  "background": {
    "scripts": ["background.js"]
  • Now, zip both the files and rename it to extension.crx

  • To check if the custom extension works fine, open a new tab in Google-Chrome and enter chrome://extensions/
  • Now, select the folder where both the manifest.json and background.js files were located (on clicking Load unpacked extension…)

  • Once the extension is loaded, you will observe the newly added icon next to the browser’s address bar; now, try loading the web application that asks you for the basic auth

Chrome options

Configure the newly created .crx chrome extension through ChromeOptions as described below

  • Ruby snippet to configure chrome extension through ChromeOptions
options = {
  'chromeOptions' => {
    'extensions' => [
      Base64.strict_encode64(File.open("../extension.crx", 'rb').read)

caps = Selenium::WebDriver::Remote::Capabilities.chrome(options)
@driver = Selenium::WebDriver.for :chrome, desired_capabilities: caps
  • The above snippet works fine in GUI mode; however, through browser’s headless mode, it doesn’t
  • Linux users, try xvfb to overcome this issue; for Ruby, you need a third party client/lib, headless to couple with Linux’s xvfb mode
gem 'headless'
require 'headless'
  • Start headless support before initiating the tests
@headless = Headless.new
  • And terminate the headless mode at exit
  • In Jenkins, you need to set the environment ready for xvfb to run tests without GUI mode
sudo yum install xorg-x11-server-Xvfb -y
sudo apt-get install xorg-x11-server-Xvfb -y
export DISPLAY=:0
  • Meanwhile, go to Manage Jenkins > Configure System; add manual export for DISPLAY :0 in the global properties itself (this step is optional)

  • Force kill Xvfb if previously running
pkill -f Xvfb || true
  • To set headless browser window size, you can still use selenium-webdriver’s native way
target_size = Selenium::WebDriver::Dimension.new(1600, 1268)
@driver.manage.window.size = target_size


Encrypt and Decrypt passwords in Ruby

Active Support

To encode and decode a text string, ruby offers a number of libraries. Let’s see how Activesupport works here,

  • Install activesupport gem
gem 'activesupport'
require 'active_support'
  • Snippet for encryption and decryption
key = SecureRandom.random_bytes(32)
crypt = ActiveSupport::MessageEncryptor.new(key)
encrypted_pwd = crypt.encrypt_and_sign("your actual password")



Base64 is used to encode and decode a value. It’s an alternate and easiest way to encrypt and decrypt values.

  • Snippet for Base64 encryption and decryption
def encrypt(input_string)

def decrypt(encrypted_string)
k = encrypt('555')
=> "NTU1\n"
=> "555"



  • Snippet for MessageEncryptor encryption and decryption
len = ActiveSupport::MessageEncryptor.key_len
=> 32
salt = SecureRandom.random_bytes(len)
key = ActiveSupport::KeyGenerator.new('password').generate_key(salt, len)
crypt = ActiveSupport::MessageEncryptor.new(key)
encrypted_data = crypt.encrypt_and_sign('777')
=> T0VjQVRtS0MrNno.....a8b8d980d9f1b35343e 
=> 777