End to End Testing using Selenium WebDriver and Java

Mohammad Faisal Khatri
17 min readApr 24, 2022

--

End to End Testing using Selenium WebDriver and Java

I was doing a POC on latest release of Selenium WebDriver, i.e. Selenium 4. My plan is to create a repository which has all the example codes showing How to use Selenium WebDriver in Web Automation with Java.

An idea hit my mind of why not start writing end to end test journey for a demo website using Selenium WebDriver which could be a practical guide for many beginners in the field and also help the community members with ready reference of the code. With the idea in mind I first selected the website to test and then prepared a test automation strategy which helped in writing the automated test scenarios for the end to end tests.

Before I begin writing about how I wrote the tests and discuss about the code, lets first let me tell you about the tools and the website under test.

Tools Used

Following tools have been used in writing and running the tests:

  1. Programming Language: Java
  2. Web Automation Tool: Selenium WebDriver(latest version)
  3. WebDriverManager is used for managing the drivers.
  4. Test Runner: TestNG
  5. Build Tool: Maven

6. Proxies that can be used for running tests

Fine with the tools now, lets get into the website details what we need to test and how can we achieve it via web automation.

OWASP Juice Shop

OWASP Juice Shop is a demo website for a juice shop which sells different flavoured juices to its customers. Using this website, users can register themselves, login and buy different juice products as per their requirement. This site also has an option to order, add address and make payment online using different payment options and allow users to deliver their product online.

The idea behind using this website for writing end to end tests is that this site is built using Material UI and its a kind of difficult to work with locators on the material UI. I faced lot of challenges in finding the locators for automating all the windows, however, I must say it was fun learning and automating this website. I can narrate a short example of the kind of challenge I faced while automating this website: The ids used for the elements are dynamic and gets change on every page refresh so you have to be very careful before selecting the locator.

Automation Test Strategy

I have derived the following automation test strategy for writing End to End Tests:

  1. User will navigate to the website and close all the pop-ups first.
  2. User will click on Login link and click on Not yet a customer link and register himself on the website.
  3. Once the Registration is successful, registered user will login in the website.
  4. After successful Login, User will add an Apple Juice and a Banana Juice to the Basket.
  5. After asserting the messages for items added to basket, user will check for the count of items displayed on top of Your Basket link.
  6. User will click on Your Basket link and check the order details and click on Checkout.
  7. User will enter a new Address for Delivery and select it to process further.
  8. User will continue further to Add Card for Payment and select the card added to make payment.
  9. On the Order Summary page, user will verify all the details like Name, Address, Order details and total amount to be paid and place order. User will also check that the count on the Your Basket link should be zero as order is already placed successfully.
  10. User will re-check the details on Order confirmation page and check for Thank You message, order confirmation and delivery message.

Github Repository

Github — Selenium4poc

All of the code which is showcased above is located in this github repository. Do mark a ⭐ and make the project popular so it reaches to the people who want to learn and upgrade and get better understanding about Web Automation with Selenium WebDriver with Java.

Getting Started

As discussed earlier, I have created this project using Maven. TestNG is used as test runner. Once the project is created we need to add the dependency for Selenium WebDriver in pom.xmlfile.

Selenium WebDriver dependency in pom.xml

For test data generation on run time I have used Java Faker which helps generating fake data on run time.

Here is the dependency I have added in pom.xmlfor Java Faker.

Java Faker dependency in pom.xml

End to End Tests

Before I begin detailing about the configurations and setup, I must tell you that I have used Page Object Model for writing the tests, as it helps organizing the tests, maintenance and easy readability and reuse.

Page Object Model

In Page Object model, a class is created for every webpage where all the related elements of the respective page is stored and also the relevant action methods are created inside that class. This way it helps in separating the page objects from the tests and helps in easy maintenance and readability of its related objects.

Let me give you an example of the Login page using Page Object Model, so, first we will be creating a new package called pages inside it we create a new class called loginpage and in this class we store all the elements of the login page, for instance, emailfield, passwordfield and login button Once the elements are located successfully. We can create a new method loginIntoWebsite which would be performing the actions on all the elements on the page for logging into the website. User will click on the email field, enter email id, then move to password field, enter password and finally click on login button which would allow him to login into the website. Once this is done, we are good to call this method in the test and perform assertions which would mark our test as complete.

Configuration

Configuration — SetupClass

As mentioned earlier in the tools section, I have used WebDriverManager in this project for maintaining the driver. It is an excellent utility which eases that pain where one has to manually go and check the browser version and accordingly download the drivers so the tests would run successfully. WebDriverManager itself takes care of all the driver downloads and thus allows the tester to focus more on the automation stuff and code rather than wasting time on driver downloads.

Moving ahead, I have used ThreadLocal which helps in executing the tests parallelly and is thread safe so each test gets executed parallelly in separate threads without conflicting with each other.

Parameter annotation from TestNG is used for taking the value of the browser from testng.xmlfile and accordingly using that value, tests are run on respective browser. Hence, required condition for the browsers are added in this Setup class which according to the value supplied in the testng.xml file will run the tests on required browser.

Also to mention here, the tests are running in headless mode. Running the tests in headless mode was considered as I have a CI Pipeline designed(which I would be covering in upcoming blog). Additionally, some more options like safebrowsing, window-size, no-sandbox, etc.. are added in the setup considering the CI pipeline setup.

Browsers taken into consideration for running tests

Following browsers are considered for running the tests, namely:

  1. Google Chrome
  2. Mozilla Firefox
  3. Microsoft Edge
  4. Opera

Proxies that could be used for running tests

There are cases when proxies may be required to run the tests, this may happen when the software teams are working in isolation at different places.

Residential proxies help in keeping the user’s information safe. It helps in hiding the real location of the user and keep them safe from being tracked. These proxies act as a middleman between the device and the internet.

NodeMaven provides high quality proxies with industry-first filtering, super sticky sessions and best customer support.

Try out NodeMaven now by using this link (Use F86 at checkout to get extra 2GB of proxy)

Test Scenarios

Setup Test

Before the actual tests begin, setupTests() method is invoked and does all the instantiation for all the respective pages class, assigns value to the variables using java faker utility and also does navigate to the website, so our foundation to run the test is set and we are all good to start testing the application.

SetupTests Method

Closing the Pop-ups

Lets begin with the testing scenarios, the first thing we would have to do is to close the pop-up messages that appear as soon as we navigate to the main page of the juice shop website.

juice-shop-main page

If we see in the image above there are two pop-up messages appearing which we need to close before we proceed to the Account Registration and Login. Since these pop-ups are active it wont allow clicking on the Account link until they are closed.

Following image shows how I have located the element for Dismiss button and Me want it! button and have closed the popups.

Main Page

A pause for 5 seconds is applied here as there is a popup message related to language selection appearing on the main page so we have to wait for it to disappear.

As I had mentioned earlier, this website is built using Material UI, hence finding the locator for dismiss button was a tough task, however I figured out that there was a class called close-dialog which was used for the dismiss button, so, using cssSelector I located the button and finally clicked on it to close it.

Register User

The User Registration Page gets opened using the following steps:

Navigate to the website >> Close all the pop-up alerts >> Click on Account Link >> Click on Login >> Click on Not yet a customer? Below is the screen shot of the user registration page.

Juice-Shop — Register User
Registration Page

From the automation point of view, first task is to find the locators on the registration page after that only we could be able to perform other actions on the fields. Finding the locators for emailId, Password and Repeat Password field was easy as it had the id allotted to it. However it was challenging to click and select the Security Question field. I will tell you in short how I overcame this challenge using the following steps:

  1. Locate the security question field.
  2. Using Actions class wait for 2 seconds and then click on the dropdown field to open.
  3. After the dropdown opens, select the security question as required and proceed.

Lets move on to the registerUser method now. This method has all the actions performing on the registration page fields and helps to register the user successfully.

Register User test

The image above is self explanatory about the test and I will not go deep into explaining it. registerUser() method takes in 4 parameters, email, password, security question and answer to security question. Test Data for Email and Password values are been generated using the java faker utility. Email and password variables are made global since we would be using those variables in login scenario as well. Once the registration is successful, system shows a text message which we would be asserting to check and confirm that registration is really successful and that marks our registration test as complete.

Helper Utility

While writing the automation tests, I found that whenever there was a text field where I had to type something I was repeating 3 lines of code every time, it was

  1. element.click()
  2. element.clear()
  3. element.sendKeys(text)

Hence I thought of creating a Helper class utility method using which could stop the code duplication and repetition. Check the following image which shows the code that was written for Helper class.

Helper class — enterText method.

Now, whenever I need to type text in a field, I just instantiate the Helper class and call the enterText() method and pass the WebElement and text in it.

Login User

Juice-shop — login screen
Login test

Once the registration is successful, user will have to come back to the login page to login in to the application. Here, user will enter the email and password which he has used while registration. If you remember we had used global variable for email and password, we would be using the same variables for login.

So, how do we check if the login is successful?

Once the user login method is executed, we are checking and verifying that on clicking on Account link we should be able to see the Logout link. If the Logout link is displayed successfully, we can conclude that the Login was successful and test passed.

“Add Product to Cart” Test

Once the login is successful, we can start with the main functional tests of the application related to ordering juices online. So, the first step to do that is select product and add them to the cart.

Juice Shop — Select Product Page
Add to cart test

The first thing I would explain here is the use of “dependsOnMethods” attribute used on line 1. This is used so we have a faster feedback incase the login fails, no further tests would be run and all other tests get skipped. Going further, in this test, we would be adding 2 products to the cart, namely, Apple Juice and Banana Juice.

ProductPage class

I faced a problem while adding a product to cart. Let me tell you in short about it. I thought it was quite easy to test this step however I was wrong. I located all the elements on the product page, wrote the code to perform actions on those respective elements. However, When I started running the tests, I got the following exception org.openqa.selenium.ElementClickInterceptedException: element click intercepted

After debugging a lot, I came to know that there was an overlay coming on top of the screen after the user logged in. And finally, got solution that I have to click on the overlay so it gets cleared and then only I would be able to click on the buttons on the product page to add products.

After clearing the overlay, next, we click on “Add to Basket” button of Apple Juice and Banana Juice. Since the success message of adding Apple Juice takes some time to disappear hence we have to add some pause time before we add Banana Juice to the cart. Same step repeated for adding Banana Juice to basket, where we add Banana Juice to cart and verify the message text to confirm that it was added successfully. One thing to note here is we are getting the text and price of the Apple and Banana Juice products and are storing it in the respective global variables so we could do kind of assertions on the text in the later test on Order Summary Page where all the order details would be displayed.

To confirm that the products are added to basket, count of the items added to the basket is also asserted, that it should have the count as “2”.

Product Checkout Test

Product checkout page
Add new Address page
Add Address details
Select Address page

There are 4 screens which we need to automate to checkout the product. Steps are as follows:

  1. From the Your Basket screen, we need to click on the Checkout button.
  2. It will take us to the next screen where we would be asked to Select Address, now, since we are checking out for the first time we will have to add a new Address to checkout.
  3. After adding the address, it will be displayed in the Select Address screen, which we need to select and proceed further to checkout by clicking on Continue button.
Checkout Page class
Address Page Class
Product Checkout test

Before we checkout the product, its better to verify the product that are added to the Cart. As discussed earlier, we have already saved the Apple and Banana Juice text and its prices in the global variable which will come handy here for verifying the text and prices from checkout screen.

Talking about the test, as usual it depends on the previous test Add product to cart, so in any case, if the previous test doesn’t pass/run for any reason, product checkout test will be skipped. And this tests starts from the step where user will first navigate to the basket where the verification for the Apple and Banana Juice text and its respective prices will take place and also its quantity that was added. This is to confirm that we are checking out the right things. An assertion is also added to match the total price of the products that will be checked out after which Checkout button will be clicked and next steps would be to the add the address and finally checkout the product. addAddressForDelivery() method actually performs the actions related to adding address, selecting it and finally completing the checkout process.

Select Delivery Option and Make Payment Test

Now, Address is selected for delivery and its time now to select the delivery option and then make payment to complete the order.

Select Delivery Option
Make Payment Page
Make Payment Page- Add new card

We have 2 windows to automate here, where in first window we should be selecting the delivery option as per the requirement and then proceed to make payment. And as we are using Page Object Model here, we would be creating two classes here — one for selecting delivery option page and second for make payment page.

Select Delivery Option Class
Select Delivery Option Test

Important thing to note here is we need to do assertions as well on this page to check that the address which we selected in the previous window appears correctly. For that, we would need to find the locators for the address related fields. And on Address line 2 on the Order Summary screen, I found that values from the full address, city, state and zip code were concatenated and displayed. Hence, a local variable for addressLineTwo is created and the mentioned variable values are concatenated in addressLineTwo variable so it would be easier to verify while we do the assertions. After that we would be selecting the delivery option and conclude the test. And as usual this test depends on previous test, i.e product checkout test.

Lets move on to the Make Payment test now. This is the shortest test of the suite so far, where we just click on Payment option, add a new card and make the payment. Since we are in non-production environment, I have used a demo credit card number from the internet to make payment.

Payment Page Class
Make Payment Test

makePayment() method is only method which is performing action in this test. It clicks on the Add New Card button and then adds the card details. Here, global variable name is used to pass the value of name to the method which will be filled in in the name field on the screen and as mentioned earlier demo credit card number is supplied. The values for expiry month and expiry year are selected from the dropdown value in the website. As there is nothing to verify, hence no assertions are made in this test.

Order Summary and Order Confirmation Test

Order Summary Page
Order Confirmation Page

Now comes the final stage where we need to verify the order summary and then place order and once order is placed, check the order confirmation screen where delivery address and order details would be displayed.

Order Summary Page

On the order summary page, we need to perform assertions mostly, as after confirming the order details, we would be clicking the Place Order button.

You can see there are lots of locators which returns strings from this page which would be used for performing assertions. Before clicking on the Place Order button, using actions class I have paused for 5 seconds as from the previous test after selecting card, a popup message was displayed which takes some time to disappear and pausing this actually helps, otherwise the popup covers the Place order button and test fails as it is unable to click on it.

Order confirmation page

Let me tell you about the Order Confirmation page now, this is the final page and after the test run, it should conclude our end to end test suite. We only need to perform some assertion checks here to confirm we are on the confirmation page. For doing that, we can check the Thanks message and also the order delivery and confirmation message and that should be fine. Additionally, we can also check the Product details and respective price and quantity. Lastly, we can check if the count in the basket is set to zero as the order is already placed and basket is expected to be empty now.

Order Summary and confirmation test

The Order Summary and Order confirmation tests concludes our end to end tests suite for juice shop.

Running the Tests

Start Juice-Shop website locally, for doing this we will make use of docker-compose-v3-juiceshop.yml which is available in the root folder of this project on GitHub.

Open terminal/command prompt and navigate to the root folder of the project and run the following command:

docker-compose -f docker-compose-v3-juiceshop.yml up -d

Once the `Juice-Shop` website is up and running, we are good to run the end-to-end tests using the juice shop website.

There are 2 ways to run the tests, those are as follows:

  1. TestNG:
Right-Click on the `test-suite\testng-juice-shop.xml` and select Run \test-suite\testng-juice-shop.xml
Running tests using TestNG

2. Maven:

To run the tests in headless mode update the value for `headless` property variable to `true`

mvn clean install -Dsuite-xml=test-suite\testng-juice-shop.xml 
-Dheadless=true

To run the tests without headless mode(to see the test running in browser) update the value for `headless` property variable to `false`

mvn clean install -Dsuite-xml=test-suite\testng-juice-shop.xml 
-Dheadless=false

Stopping the Juice Shop website running in local

docker-compose -f docker-compose-v3-juiceshop.yml down

Conclusion

To conclude, we performed an end to end testing of the Juice shop website where we started from registering the user and then logging-in in the website using that user and adding products to the basket and then checking out and verifying the order summary and order confirmation.

Hope, you got a good grasp of the code as well as the flow of the tests. If you need any help do reach out to me for assistance, I would be happy to help.

Happy Testing!!

Freelance/Paid Trainings

Contact me using my Website/LinkedIn for any Freelance work or Paid trainings related to Test Automation and Software Testing.

--

--

Mohammad Faisal Khatri

QA with 14+ years of experience in automation as well as manual testing. Freelancer, blogger and open source contributor.