Test Data Factory: Why and How to Use
November 15, 2020Easily manage Properties Files in Java with Owner
January 3, 2021Introduction
Imagine you dealing with your functional/e2e tests where you want to clean the input fields. You will, probably, use your web test automation framework to do it, right?
It seems a good and easy approach, but is it fast?
In this post, I will show you basic comparisons based on the practices we do in web test automation. I will use Selenium WebDriver using Java, but I’m sure you can reproduce it in any framework or programming language.
The problem
Let’s imagine you have a form where you need to clean all the fields to add new values (text). It is a common scenario when you are editing data.
The form
The form we will use doesn’t have many fields but will give you an idea about the problem and the possible solutions.
This form is already loaded with some data in the 6 input fields, where you can access it here. We are going to ignore the State and Check me out elements.
The possible solutions
The normal and not that-fast one
Normally all the web test automation frameworks have a method to clean an input field, and it’s the first thing that came to our minds: clean the field before using it.
We have the following test (pre and post-conditions ignored).
/ pre and post conditions ignored
@Test
void cleanUsingSelenium() {
WebElement email = driver.findElement(By.id("email"));
email.clear();
email.sendKeys("new@email.com");
WebElement password = driver.findElement(By.id("password"));
password.clear();
password.sendKeys("987654321");
WebElement address = driver.findElement(By.id("address"));
address.clear();
address.sendKeys("Viebrug");
WebElement address2 = driver.findElement(By.id("address2"));
address2.clear();
address2.sendKeys("1");
WebElement city = driver.findElement(By.id("city"));
city.clear();
city.sendKeys("Utrecht");
WebElement zipCode = driver.findElement(By.id("zipcode"));
zipCode.clear();
zipCode.sendKeys("3511 AJ");
}
As you can see we are locating each element, assigning it to a WebElement
. After we send two commands: first the clean()
to clean the value into the input field and after the sendKeys()
to fill it in with a new value.
This test took 1s 506ms to execute.
The first faster alternative
Instead of calling the clean using your favorite framework, you can send a Javascript command to clean all the fields. One of the ways to do this is by finding the form element and then executing the reset()
method to clean all the fields inside the form.
The Javascript code to clean all the fields in the form is:
document.getElementById('my-form').reset()
We have the following test to clean the input fields using a Javascript command:
// pre and post conditions ignored
@Test
void cleanByJSExecutor() {
((JavascriptExecutor) driver).executeScript("document.getElementById('my-form').reset()");
driver.findElement(By.id("email")).sendKeys("new@email.com");
driver.findElement(By.id("password")).sendKeys("987654321");
driver.findElement(By.id("address")).sendKeys("Viebrug");
driver.findElement(By.id("address2")).sendKeys("1");
driver.findElement(By.id("city")).sendKeys("Utrecht");
driver.findElement(By.id("zipcode")).sendKeys("3511 AJ");
}
You can see in the like 5 the Javascript code before starting to fill in the elements. As the code is using Selenium WebDriver + Java the JavascriptExecutor
class is in use to enable the driver to execute a Javascript code.
On lines 7 to 12, you can see only the sendKeys()
command because we already cleaned all the input fields, removing the necessity for the clean()
method.
This test took 845ms to execute.
Comparison
Using clean() method | 1s 506ms |
Using Javascript code | 845ms |
Differences | 659ms (56%) |
I know, it’s a basic comparison but we can see that the Javascript approach is 56% faster than the framework clean()
method.
It’s happening because we are sending one additional command using the framework (Selenium WebDriver). So, probably your solution cleaning the field and after filling it in inside a Page Object method can slow down your test.
Imagine you with a lot of tests that require the input clean. You can save some time during the test execution, and it’s one of the automation focus: faster feedback!
Things to take into consideration
Loop into all the fields will take the same time in JS
Instead of finding the form element and triggering the reset()
method, you could find all elements that are input fields and clean them. It’s a good alternative to clean it if you have multiple forms.
The following Javascript code can do the job:
Array.from(document.getElementsByTagName('input')).forEach(
function(element) {
element.value = '';
}
);
Loop into all the fields using a framework might be flaky
As an alternative, we could still use a web test framework to clean all the input fields. The logic is the same as the JS code above: find all the input fields and clean them.
The problem is that this alternative is flaky as the elements might have a different element internal reference, so when you try to either clean or fill an exception/problem might happen.
You can see this concrete example:
driver.findElements(By.tagName("input")).forEach(WebElement::clear);
This code finds all the elements that are input fields and kills them all. The problem is an InvalidElementStateException
that will be thrown because of a page refresh or data load during the page loading.
Final considerations
This article shows you alternatives to reduce the test execution time.
You can use any approach that works and that’s ok, but if you seek improvements this is a good alternative.
A final Java code with all mentioned methods can be found at https://gist.github.com/eliasnogueira/67da81c62cab3de2383052148e7ecafa
1 Comment
Thanks bro, now i clean the forms very fast!