Write dymanic data to a new csv file using Selenium

1. Add this below dependency to pom.xml & rebuild.

         <dependency>
            <groupId>org.apache.any23</groupId>
            <artifactId>apache-any23-csvutils</artifactId>
            <version>2.0</version>
        </dependency>


2.Create a new class which is a utility for writing the values to csv file

package utils;

import com.aventstack.extentreports.Status;
import components.Config;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;


public class WriteToCSV {

    private static WebDriver driver;

    private static final char DEFAULT_SEPARATOR = ',';

    public static void writeLine(Writer w, List<String> values) throws IOException {
        writeLine(w, values, DEFAULT_SEPARATOR, ' ');
    }

    public static void writeLine(Writer w, List<String> values, char separators) throws IOException {
        writeLine(w, values, separators, ' ');
    }

    private static String followCVSformat(String value) {

        String result = value;
        if (result.contains("\"")) {
            result = result.replace("\"", "\"\"");
        }
        return result;
    }

    public static void writeLine(Writer w, List<String> values, char separators, char customQuote) throws IOException {

        boolean first = true;

        //default customQuote is empty

        if (separators == ' ') {
            separators = DEFAULT_SEPARATOR;
        }

        StringBuilder sb = new StringBuilder();
        for (String value : values) {
            if (!first) {
                sb.append(separators);
            }
            if (customQuote == ' ') {
                sb.append(followCVSformat(value));
            } else {
                sb.append(customQuote).append(followCVSformat(value)).append(customQuote);
            }

            first = false;
        }
        sb.append("\n");
        w.append(sb.toString());
    }
}

3.Create a File Writer, add a location to save the generated csv file & Call the method like below.

// This is the default location of the csv file i.e Downloads folder 
fallback.put("downloads", new File("").getAbsolutePath() + "\\Downloads\\");

public static String getDownloads() {
        return config.getProperty("downloads");
    }

    public static void setDownloads(String downloads) {
        config.put("downloads", downloads);
    }

String csvFile = Config.getDownloads()+".csv";
FileWriter writer = new FileWriter(csvFile);
WriteToCSV.writeLine(writer, Arrays.asList("Header1","Header2","Header3"));
WriteToCSV.writeLine(writer, Arrays.asList(Data1,Data2,Data3));


4. Out put looks like below.

Header1,Header2,Header3
Data1,Data2,Data3
Advertisements

Tricks for CSS and Xpath locators used in Automation

(1) Id:
An element's id is defined as "[@id='idName']" in Xpath but "#idName" in CSS.
For example, a 'div' element with id 'panel' will be represented as below:
In Xpath locator
//div[@id='panel']
In CSS selector
css=div#panel

(2) Class:
An element's class is defined as "[@class='className']" in Xpath but ".className" in CSS.  
For example, a 'div' element with class 'panelClass' will be represented as below:
In Xpath locator
//div[@class='panelClass']
In CSS selector
css=div.panelClass
For element with multiple class we need to separate with space(" ") in Xpath and dot(".") in case of CSS. See below example,
In Xpath locator
//div[@class='panelClass1 panelClass2']
In CSS selector
css=div.panelClass1.panelClass2

(3) Any Attributes:
For selecting an element by its any of the attribute(say "name" is an attribute of a 'div' element and "type" in an "input" element) is given below:
In Xpath locator
//div[@name='continue']
//input[@type='button']
In CSS selector
css=div[name='continue']
css=input[type='button']

(4) Direct Child:
A direct child of an element is denoted as "/" in Xpath and ">" in CSS selector. See the example below for a direct child "li" for a "ul" element:
In Xpath locator
//ul/li
In CSS selector
css=ul > li

(5) Child or Subchild:
A direct child of an element is denoted as "//" in Xpath and a wehite-space(" ") in CSS selector. See the example below for a child/subchild "li" for a "ul" element:
In Xpath locator
//ul//li
In CSS selector

    
css=ul li
Note that "ul li" and "ul > li" are different. If you are confusing please go through this article.

(6) nth Child:
For finding 'nth' child, in Xpath we denote as "[n]" and in CSS we denote as ":nth-of-type(n)". See the below example,

<ol id="cars">
  <li>Audi</li>
  <li>BMW</li>
  <li>Toyota</li>
  <li>Benz</li>
  <li>Volvo</li>
</ol>    

In Xpath locator
//ul[@id='drinks']/li[3]
In CSS selector
css=ul#drinks li:nth-of-type(3)

We can use nth element ":nth-child" but the difference between ":nth-child" and ":nth-of-type(n)" is:
li:nth-child(2)
This means, select an element if It is a paragraph element and the second child of a parent.
li:nth-of-type(2)

This means, select the second paragraph child of a parent. This is less conditional.
See here for more details on difference between the above two.

If we want to select the "fifth li element" (cars) in this list, we can use the nth-of-type, which will find the fifth li in the list.
css=ul#cars li:nth-of-type(5)

On the other hand, if we want to get the "fifth element" only if it is a li element, we can use a filtered nth-child which will select again (Soft Drinks) here.
css=ul#drinks li:nth-child(5)

(7) Parent of an element:
Parent of an element can be represented as "/.." in Xpath and ":parent" in CSS selectors. For example, if you want to indicate parent of the list item of class 'blue'
   
<ul>
  <li class="red">first</li>
  <li>second</li>
  <li>third</li>
  <li>fourth</li>
  <li>fifth</li>
</ul>

In Xpath locator
//li[@class='blue']/..
In CSS selector
css=li.blue:parent

(8) Next Sibling:
Next sibling is nothing but next adjacent element which is inside the same parent on the page. An adjacent sibling combinator selector allows you to select an element that is directly after another specific element. For example, If you want to select the sibling of "li" element with class "blue" which is 'second' list item,
In Xpath locator
//li[@class='blue']/../li[2]
In CSS selector
css=li.blue + li

Similarly, if you want to indicate 'fifth' list item, see the below
In Xpath locator
//li[@class='blue']/../li[5]
In CSS selector
css=li.blue + li + li

(9) Match by Innertext:
There is a javascript methodcontains() which can be used to check the inner text of a web element. For example a link with text "Sign in"
In Xpath locator
//a[contains(text(),'Sign in')]
or
//a[contains(string(),'Sign in')]
In CSS selector
css=a:contains('Sign in')

(10) Match by Sub-string:
This is interesting and is described below. With this we can match strings with its partial text. E.g. prefix, suffix or any pattern(sub-string)
(a) Match a Sub-string(pattern):
 Taking an example of a 'div' with an 'id' that contains the text "pattern"
 
 
In Xpath locator, we need to use "contains()" to match a sub-string  //div[contains(@id,'pattern')]  In CSS selector, we need to use "*=" for matching a sub-string  css=div[id*='pattern'] (b) Match a prefix: Taking an example of a 'div' with an 'id' that starts with the text "prefixString"
In Xpath locator, we need to use "starts-with" to match a prefix //div[starts-with(@id,"prefixString")] In CSS selector, we need to use "^=" for matching a prefix css=div[id^='prefixString'] (c) Match a suffix: Taking an example of a 'div' with an 'id' that starts with the text "suffixString"
In Xpath locator, we need to use "ends-with" to match a suffix Note that "ends-with()" is a standard XPath 2.0 function only, it won't work if you are using Xpath 1.0 engine //div[ends-with(@id,"suffixString")] In CSS selector, we need to use "$=" for matching a suffix css=div[id$='suffixString'] Match a Sub-string     Match a Prefix     Match a Suffix Xpath      contains()      starts-with()      ends-with() CSS      *=      ^=      $=