Posted on Leave a comment

A Generic Template for Test Cases of User Acceptance Testing

User Acceptance Testing (UAT) is an important step in the software development process as it helps ensure that the product meets the needs and expectations of the intended users. A generic template for UAT can serve as a useful guide for planning and executing this phase of testing. In this article, we will take you through what you need to know to effectively use a generic template for User Acceptance Testing or even create your own custom template.

Make a Copy of testup.io’s Generic Template for User Acceptance Testing.

Using our Generic Template for your User Acceptance Testing

Define your Scope

The first step in using a UAT template is to define the scope of the testing. This includes identifying the specific functionality that will be tested, as well as the specific users who will be involved in the testing process. It is also important to identify any constraints or limitations that may impact the testing, such as time or budget limitations.

Go Through the Test Cases

Next, as seen in our generic template, you need to have a list of test cases that will be executed during the UAT phase. These test cases cover all aspects of the UAT functionality, including its usability, performance, and security. The test cases have also been organized in a logical and easy-to-understand manner and aligned with the overall goals and objectives of the project. We have provided a list of cases that cover Signup, Authentication, Basic App Usage, Dashboard, My Account, Device tests, Browser tests, etc. You can decide to modify this depending on your specific requirements.

Document your Results

The template has a section for documenting the results of the UAT testing. In this section, you should provide a summary of the testing results, as well as any issues or defects that were identified during the testing process. It is also important to include any recommendations for addressing these issues, as well as any follow-up actions that will be taken to ensure that the software meets the needs of the intended users.

Track the Progress of Testing

Another important aspect of the UAT template is tracking the progress of the testing. The test date, comment, and status columns of our template all work together to help you track the progress of your tests. You can add the schedule for the testing, as well as a list of the specific tasks that need to be completed in order to complete the testing on time. It is also important to include information on how the testing results will be communicated to stakeholders, such as project managers, developers, and users.

Figure 1. Generic Template for User Acceptance Testing

Additional Customi­zation Options for the UAT Template

Optionally, a section for risk management can be included. In the section, you can identify potential risks associated with the UAT process, such as the possibility of defects or issues being discovered during testing, and how these risks will be mitigated. This section could also include a plan for how to handle any unexpected issues that may arise during the testing process.

Also, you may include a section for training and support where you can provide information on how to train users on the software, as well as how to provide support during and after the UAT process. It can also include information on how users can provide feedback on the software, and how this feedback will be used to improve the software.

Conclusion

Testup:io’s generic template for User Acceptance Testing serves as a useful guide for planning and executing user-oriented tests. It includes a comprehensive list of test cases, a section for documenting the results, a section for tracking progress and a section for comments. The template will be reviewed and updated regularly, as necessary, as we are committed to ensuring that your UAT process is effective and efficient.

If you have done so already, make a copy of our User Acceptance Testing template now and start testing!

Posted on Leave a comment

Effective Test Automation Strategies for Modern Web Applications

Introduction

Test automation has become an essential part of modern software development as it allows for the efficient and consistent testing of web-based software. With the increasing complexity of web applications, it is essential to have effective test automation strategies in place to ensure the quality of the software. Although test automation is a powerful tool in software development, but it is not an all-in-one solution. When done improperly, automated tests can consume resources without providing significant value. To maximize the benefits of test automation, a comprehensive testing strategy must be developed. This includes identifying key flows, selecting the appropriate cases for automation, and avoiding common pitfalls. This article provides a guide on the best practices for test automation and how to apply them effectively.

What’s an automation test strategy?

An automation test strategy is a plan for how to use automated testing tools and techniques to determine the quality of software. It outlines the types of tests that will be automated, the tools and frameworks that will be used, and the approach that will be taken to implement and maintain the automated tests. It also defines the scope of the automation effort, including which parts of the application will be tested, and how often the tests will be run. The objective of an automation test strategy is to optimize the testing process by increasing its efficiency and effectiveness, while also minimizing the time and resources required as compared to manual testing.

Types of automated tests

Automated testing and manual testing share similar characteristics in terms of their types and objectives. The key differentiation between the two lies in their execution – while manual tests are executed and evaluated by a human tester, automated tests are executed through a script and the results are analyzed by the automation tool. Understanding the different type of automated tests and when to use them is crucial for developing an effective test automation strategy.

 The major types of automated tests include:

  1. Unit tests: These tests focus on individual units of code, such as functions or methods, and are used to ensure that they are working correctly.
  2. Integration tests: These tests check how different units of code work together, and are used to ensure that the system as a whole is functioning properly.
  3. Functional tests: These tests focus on the functionality of the application, and are used to ensure that the application is working as expected from the user’s perspective.
  4. Performance tests: These tests check how the application performs under different load conditions and are used to identify and resolve performance bottlenecks.
  5. Security tests: These tests check for vulnerabilities and potential security breaches in the application.
  6. Acceptance tests: These tests ensure that the application meets the requirements and expectations of the end-user or customer.

Steps to build an automation testing strategy

An automation testing strategy should be customized to meet the specific requirements of a project. While there is no universal method that applies to all situations, there are steps and recommendations that can be used to develop an effective automation testing strategy.

Step 1: Establish clear goals and objectives

An effective automation testing strategy requires clear and measurable goals, as it is difficult to determine success without them. Once the goals have been established, the following steps should be geared towards achieving them. The goal can be as simple as automating priority test cases for critical flows. Defining the scope of the automation testing in the initial stages also helps to prevent wasted time and resources. Without a clear scope, automated tests may overlap with manual testing or some tests may be overlooked due to confusion over whether they should be automated or tested manually. This can be a significant issue for large QA teams, and it is important to establish a precise scope to avoid such problems.

Step 2: Define requirements

This step emphasizes on the need to collaborate with stakeholders to establish automation priorities, define goals and key performance indicators (KPIs), and document the testing needs. It is important to identify the types of testing required to fulfil these needs which will inform the selection of suitable tools in a later stage.

Step 3: Evaluate Risks

In this step, focus on identifying and prioritizing areas with the highest potential business impact and automate them first. A risk-based approach can assist in this process. By prioritizing correctly, it will enable a logical order for automation, and also allow you to know when to stop automating. For instance, continuing to automate low-priority tests can be costly and may not provide much value.

Step 4: Identify Automation Test Cases

At this stage, the focus should be on determining which specific flows and features of the application need to be automated. Prioritize the areas that have the highest business impact, but also take into consideration the stability and complexity of the flows. Automating test cases that are likely to change frequently in the current or upcoming sprints is usually not cost-effective. If test cases have been previously created, highlight the parts that should be automated based on the established goals, risks, and requirements.

Step 5: Set up test data and environment

Managing the test environment and data is a vital, yet frequently overlooked aspect of an automation testing plan. Compliance with regulations such as GDPR can limit the use of data, making synthetic data a viable option. It’s beneficial to store test data in external files for easier maintenance, as changes to the data should not affect the test code. The test environment should be stable and, if necessary, testing artifacts should be cleaned up after the testing run is completed.

Step 6: Pick the Right Tool and Framework

When it comes to selecting the right tool and framework, it is important to consider the specific needs of the project and team. For example, if the team is more familiar with using Selenium, then it may be a better fit than Appium which is mainly used for mobile automation testing. Additionally, creating a proof of concept (POC) using different tools and frameworks can help in showcasing the best fit for the project. It is important to choose a tool that is flexible, easy to use and can integrate with other tools and technologies.

Step 7: Monitor your Test

Monitoring progress is crucial to understanding the current state of testing and identifying what still needs to be completed. Two effective ways to do this are:

  1. Utilize a test management tool to keep track of the automation status of tests, using statuses such as planned, automated, and outdated.
  2. Create a backlog and monitor progress in a ticket management system to easily assign tasks.

It is important to include this tracking information in the overall testing strategy and make sure all team members are aware of the chosen methods.

Step 8: Reporting

Investigating failed tests and identifying problems is a vital part of the automated process. However, it can often take longer than expected to correct underlying issues. Typically, failed tests are caused by one of four areas: Technical issues with the testing environment, defects within the application, obsolete automation scripts and bugs in the automation scripts. All these underlying issues should be reported to the technical team in charge of them.

Step 9: Establish a maintenance protocol

Test automation is not a one-time event, but a continuous process that requires ongoing attention. To ensure your test suite remains relevant and effective, it is essential to formalize the testing process. The first step is to create a system for updating scripts as necessary, but it’s also important to establish clear priorities and timelines. Keep in mind, every out-of-date test is a potential vulnerability that could make its way into the production environment. By implementing a robust maintenance protocol, you can mitigate this risk and promote the longevity of your test suite.

In addition to these strategies, it is also essential to have a continuous integration and continuous delivery (CI/CD) pipeline in place. This pipeline allows for the automated execution of the test cases and can be integrated with the software development process. This ensures that the application is tested at regular intervals and that any issues are identified and resolved quickly. A CI/CD pipeline like Github actions or Travis CI also allows for the identification of regression issues and the tracking of the test results over time.

Choose the right test automation tool

The ultimate game changer that will help you effectively apply all the strategies discussed above is to choose a best-in-class test automation tool. Testup.io is a great option in this respect; it is a visual-based no-code test tool that gives you fast results. Aside from this, your organization can now take advantage of seamless User Acceptance Testing (UAT) with testup.io. Our app allows users (both developers and non-developers) to automate User Acceptance Tests faster than the time it would take to manually test the software. This means that from a timing perspective, the business benefits of automation can begin to be realized on the second automated run. The good news is that we have also created a generic User Acceptance Testing template for your use. Ultimately, it helps cut costs significantly and guarantees that your application satisfies the user’s requirements. Click here to get started with testup.io for automated tests.

Posted on Leave a comment

How to Preserve Cookies / Localstorage Session across Tests in Cypress

Cypress clears localStorage between tests by default, which can be a concern if you’re testing out features that use localStorage. However, there is a Cypress package that lets you preserve your localStorage data across tests. Using the cypress-localstorage-commands plugin, you may utilize all browser localStorage methods through Cypress commands, and it will be saved between tests. It can also be used to make it appear as if localStorage is disabled in the browser. Follow the steps below to enable Cypress to preserve localStorage sessions across tests.

Step 1: Installation

The cypress package is distributed via npm which is bundled with node and can be installed as one of your project’s devDependencies by typing the following lines of code in your console:

npm i --save-dev cypress-localstorage-commands

Step 2: Usage

To use the Cypress localStorage package after installation, you need to import it into your projects by adding the following line of code to your cypress/support/commands.js file:

import "cypress-localstorage-commands"

Step 3: Using the commands

Now that you have rightly installed and imported the package, you can now use the following commands to use Cypress to interact with localStorage:

cy.saveLocalStorage(): Enables current localStorage values to be saved in an internal “snapshot.”

cy.restoreLocalStorage(): Causes localStorage to be restored to its previous “snapshot” saved values.

cy.clearLocalStorageSnapshot(): Clears the “snapshot” values in localStorage, cleaning out previously recorded data.

cy.getLocalStorage(item): Gets the item from the localStorage. It is the same as localStorage.getItem in Javascript. Item is the data we would like to retrieve from the localStorage.

cy.setLocalStorage(item, value): Sets the value of the localStorage item. It’s the same as localStorage.setItem in Javascript. The item parameter is the name we would like to use to store the value in localStorage while value is the data we would like to save in localStorage.

cy.removeLocalStorage(item): Deletes an item from localStorage where item refers to the name of the item to be removed.

cy.disableLocalStorage(options): This disables localStorage. It produces localStorage methods to throw errors.

Here is an Example

Suppose we would like to test an “Add To Cart” button of an eCommerce website that saves the data of the shopper to localStorage, we can perform this test by writing the following lines of code:

describe("Add to cart button", () => {
  const ADD_TO_CART_BUTTON = "#save-user-data";

  before(() => {
    cy.clearLocalStorageSnapshot();
  });

  beforeEach(() => {
    cy.restoreLocalStorage();
    cy.visit("/");
  });

  afterEach(() => {

    cy.saveLocalStorage();
  });

  it("should be visible", () => {
    cy.get(ADD_TO_CART_BUTTON).should("be.visible");
  });

  it("should not be visible after clicked", () => {
    cy.get(ADD_TO_CART_BUTTON).click();
    cy.get(ADD_TO_CART_BUTTON).should("not.be.visible");
  });

  it("should not be visible after reloading", () => {
    cy.get(ADD_TO_CART_BUTTON).should("not.be.visible");
  });
});	                            

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