Posted on Leave a comment

How to Implement Drag and Drop in Cypress

One of the best ways of providing a rich web-based experience for users is to include a way for elements to be moved easily from one point to another. This is what a feature like drag-and-drop seeks to achieve and it is exactly what is currently being used on WYSIWYG (What You See Is What You Get) development platforms like WordPress, Wix and Elementor. In this article, we will be exploring the two methods that can be used to interact with Drag and Drop UIs in Cypress and we would be providing a step-by-step guide on each method.

Method 1: Using the Cypress Drag-and-Drop plugin

Suppose we have a list of pending tasks and we would like to drag and drop some of these tasks into our to-do list using HTML Drag-and-Drop API, we can perform tests on this action in Cypress by following the steps below:

Step 1: Create a drag-and-drop.spec.js file where you would be writing your Cypress testing code

Step 2: Install the Cypress drag and drop plugin by entering the code below in your command line:

npm i cypress-drag-drop

Step 3: Once the plugin has been installed successfully, you now have access to the “drag” command which can be used to specify the destination where you would like to drop your dragged object. An example implementation can be seen below:

describe("Drag and Drop", () => {
 
    beforeEach(() => {
      cy.visit('/lists/drag-and-drop');
    });
   
    it('should drag visit beach to the to-do list', () => {
      cy.get('#visit-beach').drag('#todo-list');
    });
   
  });

Method 2: Using “DragStart” to move elements

Alternatively, we can perform drag-and-drop tests in Cypress using the DragStart method. This method does not require us to install a plugin. However, we would need to write some extra lines of code. Recalling our previous example of a to-do list, to perform this same test using DragStart, we would need to specify a data transfer object, the id of the item we want to drag and the destination to which we would like to drop the object.  An example implementation to be written in the drag-and-drop.spec.js file can be found below:

describe("Drag and Drop", () => {
 
    beforeEach(() => {
      cy.visit('/lists/drag-and-drop');
    });
    
    it('should drag visit beach to the to-do list', () => {
      const dataTransfer = new DataTransfer();
   
      cy.get('#visit-beach').trigger('dragstart', {
        dataTransfer
      });
   
      cy.get('#todo-list').trigger('drop', {
        dataTransfer
      });
    });  
   
  });
Posted on Leave a comment

How to handle Async code in Cypress.io

In Javascript, there are two major ways through which a code can be executed. They include:

  1. Synchronous JavaScript: The program runs in sequential order; that is, the second line of code can’t be executed until the first line of code has been completed correctly.
  2. Asynchronous JavaScript: All the code runs at the same time. It is unconcerned about the previous code’s state.

It is worthy to note that most API-based or data retrieval events are executed using asynchronous JavaScript. The primary reason is that performing these events take a while, hence instead of the code running in a step-by-step sequence, asynchronous JavaScript is used such that the code returns a “Promise” that it would retrieve data from the API/ database and then execute other lines of code. However, Cypress comes with a “then” method which is used to specify what happens once the data has been retrieved from the API. This is similar to the way JavaScript handles asynchronous code.

An Illustration

Suppose we want to test a piece of asynchronous JavaScript code to retrieve a list of food items from an API, we can perform a test for this using the following lines of code:

describe("asynchronous and promises", () => {
  it("loading the page", () => {
    Cypress.on("uncaught:exception", (err, runnable) => {
      return false;
    });
    cy.visit("https://foodlist.com/foods").then(() => {
      cy.get("#first.col-lg-3").select("Rice");
    });
    cy.get("select")
      .select("Rice", "Hamburger", "Pizza", "Hot dog")
      .invoke("val")
      .should("deep.equal", "Pie", "Porridge", "Pasta", "Ice cream")
      .then(() => {});
  });
});

Once the food data is retrieved from the food API, we can then select a food type like Rice out of the list of foods that are returned as indicated above.

Posted on Leave a comment

How to access a new window in Cypress

It is critical to know that Cypress does not support the handling of new browser tabs and windows out of the box, as stated on their permanent trade-offs page. However, as the framework has grown, there are now many workarounds that can be leveraged to fulfil these goals. In this article, we will take a deep dive into how to open new windows in Cypress.

Step 1

Create a new folder titled “Integration”, create two new files in the folder titled spec.js and spy-before-load.js. In your spec.js file, copy and paste the following code:

reference types="cypress" />
describe('window open', function () {
    it('opens a new window with page1', function () {
      // window.open is called on click
      // thus we can create method stub after the cy.visit
      // but before cy.click
      cy.visit('/index.html')
      cy.window().then((win) => {
        cy.stub(win, 'open').as('windowOpen')
      })
  
      cy.get('#open-window').click()
      cy.get('@windowOpen').should('be.calledWith', 'page1.html')
    })
  })

spec.js stubs the window.open method using cy.stub(). Because the application executes window.open after the click, we create the method stub after cy.visit

In your spy-before-load.js file, copy and paste the following code:

<reference types="cypress" />
describe('application', function () {
    beforeEach(function () {
      // application prints "hello" to the console
      // during the page load, thus we need to create
      // our spy as soon as the window object is created but
      // before the page loads
     
  cy.visit('/index.html', {
        onBeforeLoad (win) {
          cy.spy(win.console, 'log').as('console.log')
        },
      })
    })
  
    it('prints hello on load', function () {
      cy.get('@console.log').should('be.calledWith', 'hello')
    })
  })

spy-before-load.js starts spying on console.log during cy.visit to confirm that console.log(‘hello’) is called when the page loads.

Step 2

Using cy.spy() for a window.open event, write a test to ensure that while executing the action in your program, the window.open event is called.

cy.visit('http://localhost:3000', {
  onBeforeLoad(win) {
    cy.stub(win, 'open')
  }
})

// Do the action in your app like cy.get('.open-window-btn').click()

cy.window().its('open').should('be.called'

Step 3

Use cy.visit() in a new test to navigate to the URL already opened in the new window, then fill in the fields and click the buttons as you would in a Cypress test.

cy.visit('http://localhost:3000/new-window')
Posted on Leave a comment

How to check if an element exists or not using Cypress.io

Element presence is one of the first things you should test with Cypress in your project. In this article, we will look at how to test if an element exists or not. Also, if it exists, how do you check whether it is visible or not.

Check if Element exists

If you wish to check if an element exists without failing, you need to use conditional testing. Let’s take an example of a web page that has both a Banner and a Popup element with class ‘banner’ and ‘pop’. We can check if these elements exist on the webpage in the following way:

cy.get('body')
  .then($body => {
    if ($body.find('.banner').length) {
      return '.banner';
    }
    return '.popup';
  })
  .then(selector => {
    cy.get(selector);
  });

After running this code, you will get the body element returned. Subsequently, you can query the element within the body using the “find” method, the element’s ID or class and a callback function. If the element exists, the callback function will return true. If the element does not exist, the callback function will return false.

Check if Element is visible

Let us reconsider our example of the webpage with a banner and a popup. As the popup would not be visible initially, to test for its visibility at any time, we can write the following code:

cy.get('popup')
    .then($popup => {
        if ($popup.is(':visible')) {
            cy.get('popup').click()
        } 
        else{
            return
        }
    })

The code above checks if the popup element is visible. The callback function then gets a return value $popup which either returns null or the popup element object. If the popup element object is returned, then the code proceeds to click on the popup. However if null, the code exits at the return code block. All this is made possible through Cypress conditional testing feature.

Posted on Leave a comment

How to Select/Get the Drop-down Option in Selenium 2

Text fields, buttons, checkboxes, dropdowns, and other web elements can be found on a web page. With the widespread use of forms on websites these days, we occasionally run into dropdowns. There are several sorts of dropdowns, the most common of which are single-select (which allows picking only one value) and multi-select (which allows selecting multiple values. Selenium WebDriver has a class called “Select” that has numerous methods for dealing with dropdowns. 

In Selenium webdriver, we can choose from a dropdown menu, the Selenium Select class can be used to manipulate the dropdowns. In HTML, the select tag represents a dropdown while the option tag represents the entries in the dropdown.

Selenium WebDriver’s “org.openqa.selenium.support.ui” package provides the “Select” class. You can build a Select object by bypassing the object of the “WebElement” class, which displays the object returned by the WebElement’s matching locator. As a result, you may build a Select class object with the following syntax:

Select select = new Select(WebElement webelement);

The WebElement object returned by the locators of the chosen element is the only parameter accepted by the Select class constructor.

The “Select” class has a number of methods for dealing with dropdown menus. This include:

  • selectByIndex
  • selectByValue
  • selectByVisibleText

selectByIndex

This approach uses the dropdown option’s index number to choose it. As an argument, we offer an integer value for the index number. The index starts counting at zero. It has the following syntax:

selectByIndex(int arg0) : void

selectByValue

This approach uses the value of the dropdown option to choose it. As an argument, we offer a string value as the value. It has the following syntax:

selectByValue(String arg0) : void

selectByVisibleText

This approach allows you to choose one choice from a dropdown or a multi-select dropdown depending on the text in the dropdown. The String value of the <select> element must be given as an input. It has the following syntax:

selectByVisibleText(String arg0): void

How to select multiple values from a dropdown in Selenium?

If the <select> tag contains multiple attributes, it means that the dropdown allows selecting multiple values. We can use any of the methods we used to select one value from the dropdown to select multiple values by invoking the methods multiple times for different values. The Select class provides the “isMultiple()” method, which determines whether the select web element allows for multiple selections. It returns a boolean value, i.e., True/False, without taking any argument.

isMultiple(): Boolean

You can use the Select class’s various select methods on the many values you plan to select once you’ve determined whether the web element is multi-select or not.

How to get Options from a Dropdown in Selenium?

The Select class provides the following methods to get the options of a dropdown:

  • getOptions()
  • getFirstSelectedOption()
  • getSelectedOptions()

getOptions()

Sometimes, you may need all of the options in a dropdown or multi-select box. This is where the Select class’s getOptions() method comes in handy. It has the following syntax:

getOptions(): List<WebElement>

getFirstSelectedOption()

This method returns the dropdown’s first selected choice. This function will return the selected value of the dropdown if it is a single-select dropdown, and the first selected value of the dropdown if it is a multi-select dropdown. It has the following syntax:

getFirstSelectedOption(): WebElement

getAllSelectedOptions()

This function retrieves all of the dropdown’s selected options. If the dropdown is a single-select dropdown, this method will return the dropdown’s only selected value; if the dropdown is a multi-select dropdown, this method will return all of the dropdown’s selected values. It has the following syntax:

getAllSelectedOptions():List<WebElement>

How to deselect a value from a dropdown in Selenium?


We can deselect values in a DropDown & Multi-Choose just like we may select them in a DropDown & Multi-Select. However, the deselect approach is only applicable to Multi-Select. The various deselect methods outlined here can be used to deselect pre-selected items from a Multi-select element:

  • deselectAll()
  • deselectByIndex()
  • deselectByValue()
  • deselectByVisibleText()

deselectAll

This approach will remove all of the dropdown’s chosen entries. It has the following syntax:

deselectAll(): void

deselectByIndex()

The Select class provides the deselectByIndex() method, which works similarly to the selectByIndex() method for deselecting an option from a dropdown menu. To deselect an option, use the option’s index number. It has the following syntax:

deselectByIndex(int arg0): void

deselectbyValue()

The Select class provides the deselectByValue() method, which works similarly to the selectByValue() method for selecting an option from a dropdown menu. You can deselect an option by changing its value. It has the following syntax:

deselectByValue(String arg0): void

deselectByVisibleText

The Select class provides the deselectByVisibleText() method, which works similarly to the selectByVisibleText() method for selecting an option from a dropdown menu. To deselect an option, utilize the option’s text. It has the following syntax:

deselectByVisibleText(String arg0): void

Posted on Leave a comment

How Do You Make Selenium 2.0 Wait for Page Load?

A typical website is usually made up of a backend that calls dynamic data from a database. As this data is being called through an asynchronous process, it takes a while for it to be ready, hence increasing the time it takes for a website to load completely. Selenium is a great tool for automated testing of websites, it speeds up the testing process and produces results quickly. However, as a result of the slow asynchronous process explained earlier, there is a need to make Selenium wait.

Selenium wait ensures that elements of the applications load completely so that test actions can be performed on them. This usually involves pausing the execution of the code for a while until the data is fully loaded.

Types of Selenium Waits

There are three main implementations of Waits in Selenium:

  1. Through Implicit Wait
  2. Through Explicit Wait
  3. Through Fluent Wait

1. Implicit Wait

Implicit wait is pretty straightforward as it simply tells the WebDriver component of Selenium to wait for a particular amount of time, say 10 seconds. This is similar to a timeout method in Javascript. The time specified for waiting should typically be an estimate of how long it takes the page to load. Hence, Implicit wait cannot work effectively unless the tester knows how long it takes for the page to load.

Let’s say a website under test takes ten seconds to load a page until a particular element shows up. In that case, you can set implicit wait for 10 seconds. The test will pause, and once the time passes, WebDriver will continue to run the script as planned.

A simple implementation of Implicit wait can be performed with the following code:

WebDriver driver => new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://testup.io");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));

It is important to note that the Implicit Wait function will only work as long as the current browser is open. That means that the time taken for loading components will reoccur upon page reload.

2. Explicit Wait

The explicit wait is a little bit more complex. It works in the form of an “if” conditional statement such that Selenium does not run unless certain conditions are met.  A great use case for explicit wait is when you want a certain action like a popup to run, or you would like the user to navigate to a certain part of the page before running Selenium. Implicit wait cannot be used in this case because the time taken for the condition to be fulfilled may vary with the user, hence the need to use Explicit wait.

An example code of an implementation of Explicit wait can be found below:

from selenium.webdriver.common.by import By.ID
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
 
driver = webdriver.Firefox()
driver.get("http://testup.io") #This is Testup's website URL
try:
    elem = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "Element_to_be_found")) #This is a dummy element
    )
finally:
driver.quit()

3. Fluent Wait

The fluent wait is similar to explicit wait, however aside from defining a condition after which Selenium starts to run, you can also define the frequency with which you want to check for a specified condition. The best use case for this type of wait is for websites that have elements that take much longer to load than others.  Fluent wait enables us to keep checking for the element at regular intervals and enable Selenium to run once the condition has been met.

An example code of an implementation of Fluent wait can be found below:

//Declare and initialise a fluent wait
FluentWait wait = new FluentWait(driver);
//Specify the timout of the wait
wait.withTimeout(5000, TimeUnit.MILLISECONDS);
//Specify polling time
wait.pollingEvery(250, TimeUnit.MILLISECONDS);
//Specify what exceptions to ignore
wait.ignoring(NoSuchElementException.class)

//This is how we specify the condition to wait on.
wait.until(ExpectedConditions.alertIsPresent());

Fluent waits are also called smart waits. This is because they do not wait for the maximum time specified in .withTimeout(5000, TimeUnit.MILLISECONDS) before they run, rather they wait for the time till the condition specified in .until(YourCondition) method becomes true.

Posted on Leave a comment

How to Get Attribute of Element from Selenium?

In Selenium webdriver, we can use the getAttribute() method to get the value of an attribute. The attribute and its value appear as a key-value pair in HTML code.

Disabled, alt, id, href, style, title, and src are among the most well-known html properties. The value of the attribute we wish to get is supplied to the method as an argument.

Let’s have a look at how to collect attributes for an input field. The HTML for the input tag is shown below.

<input name="textField" class="textClass" type="text" aria-label="Input field" placeholder="Enter your name" id="name" label='Enter your name' />

With the code below, we can get the name, class and ID of the input Field.

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class GetAttributes {

    public WebDriver driver;
    private By byInputField = By.name("textField");
                            
    @BeforeClass
    public void setUp() {
        driver = new FirefoxDriver();
        driver.get("https://testup.io");
    }

    @Test
    public void getAttribute_TextFieldName() {
        WebElement inputTextField = driver.findElement(byInputField);
        System.out.println("Name of the input field is:- " +inputTextField.getAttribute("name"));
    }

    @Test
    public void getAttribute_Id() {
        WebElement inputTextField = driver.findElement(byInputField);
        System.out.println("Id of the input field is:- "+ inputTextField.getAttribute("id"));
    }

    @Test
    public void getAttribute_class() {

        WebElement inputTextField = driver.findElement(byInputField);
        System.out.println("Class of the Input Field is:- "+ inputTextField.getAttribute("class"));

    }

    @Test
    public void getAttribute_InvalidAttribute() {

        WebElement inputTextField = driver.findElement(byInputField);
        //Will return null value as the 'status' attribute doesn't exists
        System.out.println("Invalid Attribute status of the input field is:- "+ inputTextField.getAttribute("status"));
    }
    
    @Test
    public void getAttribute_TextFieldLabel() {

        WebElement inputTextField = driver.findElement(byInputField);
        System.out.println("Label of the input field is:- "+ inputTextField.getAttribute("aria-label"));
    }

    @AfterClass
    public void tearDown() {
        driver.quit();
    }
}

Output

Label of the button is: Enter your name
Name of the button is: textField
Id of the button is: name
Invalid Attribute status of the button is: null
Class of the button is: textClass
PASSED: getAttribute_inputTextFieldLabel
PASSED: getAttribute_inputTextFiedlName
PASSED: getAttribute_Id
PASSED: getAttribute_InvalidAttribute
PASSED: getAttribute_class

Posted on Leave a comment

How to Include Scroll Element into View with Selenium

Sometimes, you are required to perform a test action on an element that is not present in the viewable area of a webpage. What do you do in such a situation? With Selenium, you cannot perform a scrolling action directly. However, this can be achieved with two methods:

  1. Use of JavaScript Executor
  2. Use of actions class to control the HTML DOM element

Method 1: Use of JavaScript Executor

Selenium can execute commands in JavaScript with the help of the execute_script() method. For the JavaScript solution, we have to pass true value to the method scrollIntoView() to identify the object below our current location on the page.

Code Implementation with Javascript Executor can be found below:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.JavascriptExecutor;
public class ScrollToViewJs{
   public static void main(String[] args) {
      System.setProperty("webdriver.chrome.driver",
      "C:\\Users\\ghs6kor\\Desktop\\Java\\chromedriver.exe");
      WebDriver driver = new ChromeDriver();
      String url = " https://testup.io/documentation/";
      driver.get(url);
      driver.manage().timeouts().implicitlyWait(12, TimeUnit.SECONDS);
      // identify element
      WebElement l=driver.findElement(By.xpath("//*[text()='Book Onboarding Session']"));
      
// Javascript executor
      ((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView(true);", l);
      Thread.sleep(800);
      driver.quit();
   }
}

Method 2: Use of actions class to control the HTML DOM element

While working with the Actions class to scroll to view, we have to use the moveToElement() method. This method shall perform mouse movement till the middle of the element.

Code implementation with Action class can be found below:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.interactions.Action;
import org.openqa.selenium.interactions.Actions;
public class ScrollToViewActions{
   public static void main(String[] args) {
      System.setProperty("webdriver.chrome.driver",
      "C:\\Users\\ghs6kor\\Desktop\\Java\\chromedriver.exe");
      WebDriver driver = new ChromeDriver();
      String url = " https://testup.io/documentation/;
      driver.get(url);
      driver.manage().timeouts().implicitlyWait(12, TimeUnit.SECONDS);
      // identify element
      WebElement l=driver.findElement(By.xpath("//*[text()='Book Onboarding Session']"));
      // Actions class with moveToElement()
      Actions a = new Actions(driver);
      a.moveToElement(l);
      a.perform();
      driver.quit();
   }
}
Posted on Leave a comment

How to run Javascript in Selenium using Python

Javascript is the only programming language that can be used for both frontend and backend development, hence it is safe to say that it is the “programming language of the web” as 100% of responsive websites use Javascript. We use Selenium to do automated testing of web apps or websites or to just automate the web browser. However, the Selenium testing framework is built with Java, C#, Ruby, and Python.

For specific test case scenarios like automatic scrolling and waiting on page load, there is a need for us to write custom Javascript code within Selenium. To achieve this, we typically have to use Python to run Javascript within the Selenium webdriver using the Javascript executor method. The Document Object Model communicates with the elements on the page with the help of Javascript. Selenium executes the Javascript commands by taking in the argument in the execute_script method (the commands to be executed are passed as arguments to the method).

Upon page load, sample code to create the alert “Page Loaded successfully” can be found below:

from selenium import webdriver
driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe")
driver.implicitly_wait(0.5)
driver.get("https://testup.io/documentation/")
# to scroll till page bottom
driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")from selenium import webdriver
driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe")
driver.implicitly_wait(0.5)
driver.get("https://testup.io/documentation/")
# to scroll till page bottom
driver.execute_script("alert('Page Loaded successfully')")

Asynchronous Javascript

Asynchronous Javascript functions typically use the “async” and “await” keywords to categorize functions as asynchronous and wait for the function to run respectively. Async Javascript is typically used for API calls to a database or general CRUD functions.

To run asynchronous Javascript functions in Selenium, you would need to run the executeAsyncScript() method which takes in both the Javascript function you would like to run and the specific wait time by which the function is expected to have been run. This wait time is usually less than 5 seconds (or 5000 milliseconds).

An example code implementation to sleep a browser after 5 seconds of visiting Testup.io can be found below:

import java.util.concurrent.TimeUnit;       

import org.openqa.selenium.JavascriptExecutor;      
import org.openqa.selenium.WebDriver;       
import org.openqa.selenium.firefox.FirefoxDriver;       
import org.testng.annotations.Test;     
            
public class JavaSE_Test {              

    @Test       
    public void Login()                     
    {       
                
        WebDriver driver= new FirefoxDriver();          

        //Creating the JavascriptExecutor interface object by Type casting      
        JavascriptExecutor js = (JavascriptExecutor)driver;     
                
        //Launching the Site.       
        driver.get("https://testup.io/ /");           
     
          //Maximize window     
          driver.manage().window().maximize();      
                
          //Set the Script Timeout to 20 seconds        
          driver.manage().timeouts().setScriptTimeout(20, TimeUnit.SECONDS);            
             
          //Declare and set the start time      
          long start_time = System.currentTimeMillis();         
                   
          //Call executeAsyncScript() method to wait for 5 seconds      
          js.executeAsyncScript("window.setTimeout(arguments[arguments.length - 1], 5000);");           
                
         //Get the difference (currentTime - startTime)  of times.      
         System.out.println("Passed time: " + (System.currentTimeMillis() - start_time));                   
                            
    }       
}