December 28, 2015

Automate Amazon: CommonUtils, methods and exceptions

This post is third of a series of nine. Need to go back to the beginning?

The Selenium WebDriver API provides the basic methods to manipulate a browser to perform actions, such as navigating to a web page, but it doesn't have all the functionality we would need. What if we wanted to add in exception handling, such as if the web page was not found? What if we wanted to throw a customized error to a log file when the page was not found? What if, even upon a success, we wanted to write a message to the log?

A Common Utilities library, such as one they are using at my workplace, can be developed to handle these cases. Each Selenium API method is wrapped in try / catch / throw blocks for exception handling, built-in with logging functionality. When things go wrong, clear and concise error messages will save a lot of time debugging if the issue was with the server, with the code of the site, or the tests themselves.



Creating Methods to Navigate to a Web Page


Navigating to Amazon.com's home page is pretty simple with WebDriver. All it takes is one driver.get statement in order to navigate to the login page:

 driver.get("http://www.amazon.com/");  

But what if you wanted to add functionality to write to the log console every time you use WebDriver to navigate to a web page? This means you would have to enter two lines of code per driver.get statement.
  System.out.println("Navigating to: http://www.amazon.com/");  
  driver.get("http://http://www.amazon.com/");  

Let's say you also wanted to add even more:
  • Logging functionality when an action is performed
  • Catch any errors if the action failed
  • Throw an error to the logs detailing if an error ever happened
  • Include any wait statements, if a page is known to be slow loading. 

To satisfy all these new requirements, at work they came up with the following method for their CommonUtils library, navigateToURL: 

 public void navigateToURL(String URL) {  
     System.out.println("Navigating to: " + URL);  
     System.out.println("Thread id = " + Thread.currentThread().getId());  
     try {  
       _driver.navigate().to(URL);  
     } catch (Exception e) {  
       System.out.println("URL did not load: " + URL);  
       throw new TestException("URL did not load");  
     }  
 }  

To use this method, we can use this method in a test, passing in the URL as a String:

navigateToURL("http://www.amazon.com/");

Now imagine if you had a whole library where all the Selenium WebDriver functions are wrapped in try / catch / throw blocks, logging functionality is added, threads have identification numbers listed, and any optional wait statements are included.

Methods in the CommonUtils Library


These are the methods in the CommonUtility we can use:

  • navigateToURL(String URL)
  • getPageTitle()
  • getElement(By selector)
  • sendKeys(By selector, String value)
  • clearField(WebElement element)
  • click(By selector)
  • waitForElementToBeClickable(By selector )
  • waitForElementToBeVisible(By selector)

How to use the Methods:


Selectors can be found By Id or By CSS Selector. If we wanted to grab the Username textbox, the Password textbox, or the Sign In button of the Sign In page, we could:

  • Username: getElement(By.cssSelector("#ap_email")
  • Password: getElement(By.cssSelector("#ap_password")
  • Login Button: getElement(By.cssSelector("#signInSubmit")


... And wherever these CommonUtils methods are used, such as in the Page Objects, we need to:

  • Import the CommonUtils library. 
  • Extend the Class to inherit the methods declared in CommonUtils. 


All test code can be found on GitHub at Automate-Amazon.


CommonUtils.java
1:  package utils;  
2:  import org.apache.commons.lang3.StringUtils;  
3:  import org.openqa.selenium.*;  
4:  import org.openqa.selenium.interactions.Actions;  
5:  import org.openqa.selenium.support.ui.ExpectedConditions;  
6:  import org.openqa.selenium.support.ui.Select;  
7:  import org.openqa.selenium.support.ui.WebDriverWait;  
8:  import org.testng.TestException;  
9:  import java.util.ArrayList;  
10:  import java.util.List;  
11:  /**  
12:   * Created by tmaher on 12/21/2015.  
13:   */  
14:  public abstract class CommonUtils {  
15:    private static int timeout = 10;  
16:    public CommonUtils() {  
17:      _driver = DriverUtils.getDriver();  
18:    }  
19:    public static WebDriver _driver;  
20:    public WebDriverWait wait;  
21:    public Actions actions;  
22:    public Select select;  
23:    public void navigateToURL(String URL) {  
24:      try {  
25:        _driver.navigate().to(URL);  
26:      } catch (Exception e) {  
27:        System.out.println("FAILURE: URL did not load: " + URL);  
28:        throw new TestException("URL did not load");  
29:      }  
30:    }  
31:    public void navigateBack() {  
32:      try {  
33:        _driver.navigate().back();  
34:      } catch (Exception e) {  
35:        System.out.println("FAILURE: Could not navigate back to previous page.");  
36:        throw new TestException("Could not navigate back to previous page.");  
37:      }  
38:    }  
39:    public String getPageTitle() {  
40:      try {  
41:        return _driver.getTitle();  
42:      } catch (Exception e) {  
43:        throw new TestException(String.format("Current page title is: %s", _driver.getTitle()));  
44:      }  
45:    }  
46:    public String getCurrentURL() {  
47:      try {  
48:        return _driver.getCurrentUrl();  
49:      } catch (Exception e) {  
50:        throw new TestException(String.format("Current URL is: %s", _driver.getCurrentUrl()));  
51:      }  
52:    }  
53:    public WebElement getElement(By selector) {  
54:      try {  
55:        return _driver.findElement(selector);  
56:      } catch (Exception e) {  
57:        System.out.println(String.format("Element %s does not exist - proceeding", selector));  
58:      }  
59:      return null;  
60:    }  
61:    public String getElementText(By selector) {  
62:      waitUntilElementIsDisplayedOnScreen(selector);  
63:      try {  
64:        return StringUtils.trim(_driver.findElement(selector).getText());  
65:      } catch (Exception e) {  
66:        System.out.println(String.format("Element %s does not exist - proceeding", selector));  
67:      }  
68:      return null;  
69:    }  
70:    public List<WebElement> getElements(By Selector) {  
71:      waitForElementToBeVisible(Selector);  
72:      try {  
73:        return _driver.findElements(Selector);  
74:      } catch (Exception e) {  
75:        throw new NoSuchElementException(String.format("The following element did not display: [%s] ", Selector.toString()));  
76:      }  
77:    }  
78:    public List<String> getListOfElementTexts(By selector) {  
79:      List<String> elementList = new ArrayList<String>();  
80:      List<WebElement> elements = getElements(selector);  
81:      for (WebElement element : elements) {  
82:        if (element == null) {  
83:          throw new TestException("Some elements in the list do not exist");  
84:        }  
85:        if (element.isDisplayed()) {  
86:          elementList.add(element.getText().trim());  
87:        }  
88:      }  
89:      return elementList;  
90:    }  
91:    public void click(By selector) {  
92:      WebElement element = getElement(selector);  
93:      waitForElementToBeClickable(selector);  
94:      try {  
95:        element.click();  
96:      } catch (Exception e) {  
97:        throw new TestException(String.format("The following element is not clickable: [%s]", selector));  
98:      }  
99:    }  
100:    public void scrollToThenClick(By selector) {  
101:      WebElement element = _driver.findElement(selector);  
102:      actions = new Actions(_driver);  
103:      try {  
104:        ((JavascriptExecutor) _driver).executeScript("arguments[0].scrollIntoView(true);", element);  
105:        actions.moveToElement(element).perform();  
106:        actions.click(element).perform();  
107:      } catch (Exception e) {  
108:        throw new TestException(String.format("The following element is not clickable: [%s]", element.toString()));  
109:      }  
110:    }  
111:    public void sendKeys(By selector, String value) {  
112:      WebElement element = getElement(selector);  
113:      clearField(element);  
114:      try {  
115:        element.sendKeys(value);  
116:      } catch (Exception e) {  
117:        throw new TestException(String.format("Error in sending [%s] to the following element: [%s]", value, selector.toString()));  
118:      }  
119:    }  
120:    public void clearField(WebElement element) {  
121:      try {  
122:        element.clear();  
123:        waitForElementTextToBeEmpty(element);  
124:      } catch (Exception e) {  
125:        System.out.print(String.format("The following element could not be cleared: [%s]", element.getText()));  
126:      }  
127:    }  
128:    public void waitForElementToDisplay(By Selector) {  
129:      WebElement element = getElement(Selector);  
130:      while (!element.isDisplayed()) {  
131:        System.out.println("Waiting for element to display: " + Selector);  
132:        sleep(200);  
133:      }  
134:    }  
135:    public void waitForElementTextToBeEmpty(WebElement element) {  
136:      String text;  
137:      try {  
138:        text = element.getText();  
139:        int maxRetries = 10;  
140:        int retry = 0;  
141:        while ((text.length() >= 1) || (retry < maxRetries)) {  
142:          retry++;  
143:          text = element.getText();  
144:        }  
145:      } catch (Exception e) {  
146:        System.out.print(String.format("The following element could not be cleared: [%s]", element.getText()));  
147:      }  
148:    }  
149:    public void waitForElementToBeVisible(By selector) {  
150:      try {  
151:        wait = new WebDriverWait(_driver, timeout);  
152:        wait.until(ExpectedConditions.presenceOfElementLocated(selector));  
153:      } catch (Exception e) {  
154:        throw new NoSuchElementException(String.format("The following element was not visible: %s", selector));  
155:      }  
156:    }  
157:    public void waitUntilElementIsDisplayedOnScreen(By selector) {  
158:      try {  
159:        wait = new WebDriverWait(_driver, timeout);  
160:        wait.until(ExpectedConditions.visibilityOfElementLocated(selector));  
161:      } catch (Exception e) {  
162:        throw new NoSuchElementException(String.format("The following element was not visible: %s ", selector));  
163:      }  
164:    }  
165:    public void waitForElementToBeClickable(By selector) {  
166:      try {  
167:        wait = new WebDriverWait(_driver, timeout);  
168:        wait.until(ExpectedConditions.elementToBeClickable(selector));  
169:      } catch (Exception e) {  
170:        throw new TestException("The following element is not clickable: " + selector);  
171:      }  
172:    }  
173:    public void sleep(final long millis) {  
174:      System.out.println((String.format("sleeping %d ms", millis)));  
175:      try {  
176:        Thread.sleep(millis);  
177:      } catch (InterruptedException ex) {  
178:        ex.printStackTrace();  
179:      }  
180:    }  
181:    public void selectIfOptionTextContains(By selector, String searchCriteria) {  
182:      waitForElementToBeClickable(selector);  
183:      Select dropdown = new Select(getElement(selector));  
184:      List<WebElement> options = dropdown.getOptions();  
185:      String optionText = "";  
186:      if (options == null) {  
187:        throw new TestException("Options for the dropdown list cannot be found.");  
188:      }  
189:      for (WebElement option : options) {  
190:        optionText = option.getText().trim();  
191:        boolean isOptionDisplayed = option.isDisplayed();  
192:        if (optionText.contains(searchCriteria) && isOptionDisplayed) {  
193:          try {  
194:            dropdown.selectByVisibleText(optionText);  
195:            break;  
196:          } catch (Exception e) {  
197:            throw new NoSuchElementException(String.format("The following element did not display: [%s] ", selector.toString()));  
198:          }  
199:        }  
200:      }  
201:    }  
202:    public void selectIfOptionTextEquals(By selector, String searchCriteria) {  
203:      waitForElementToBeClickable(selector);  
204:      Select dropdown = new Select(getElement(selector));  
205:      List<WebElement> options = dropdown.getOptions();  
206:      String optionText = "";  
207:      if (options == null) {  
208:        throw new TestException("Options for the dropdown list cannot be found.");  
209:      }  
210:      for (WebElement option : options) {  
211:        optionText = option.getText().trim();  
212:        boolean isOptionDisplayed = option.isDisplayed();  
213:        if (optionText.equals(searchCriteria) && isOptionDisplayed) {  
214:          try {  
215:            dropdown.selectByVisibleText(optionText);  
216:            break;  
217:          } catch (Exception e) {  
218:            throw new NoSuchElementException(String.format("The following element did not display: [%s] ", selector.toString()));  
219:          }  
220:        }  
221:      }  
222:    }  
223:    public List<String> getDropdownValues(By selector) {  
224:      waitForElementToDisplay(selector);  
225:      Select dropdown = new Select(getElement(selector));  
226:      List<String> elementList = new ArrayList<String>();  
227:      List<WebElement> allValues = dropdown.getOptions();  
228:      if (allValues == null) {  
229:        throw new TestException("Some elements in the list do not exist");  
230:      }  
231:      for (WebElement value : allValues) {  
232:        if (value.isDisplayed()) {  
233:          elementList.add(value.getText().trim());  
234:        }  
235:      }  
236:      return elementList;  
237:    }  
238:  }  
All Source Code can be found in T.J. Maher's Automate-Amazon repository. 


NEXT: We finally can write a Sign-In Test! >>

-T.J. Maher
 Sr. QA Engineer, Fitbit
 Boston, MA

// Automated tester for [ 9 ] month and counting!

Please note: 'Adventures in Automation' is a personal blog about automated testing. It is not an official blog of Fitbit.com





15 comments:

Ariel Wilson said...

I have been looking for a way to handle my dissertation – I have been looking for dissertation conclusion services and I asked my friend to share a service with me that could write my dissertation conclusion and he sends me this post – I guess I have to look one up on my own. I hope I find one soon. Ah, my brother may find this post useful as he is a computer science student.

vé máy bay từ canada về việt nam said...

Liên hệ Aivivu, đặt vé máy bay tham khảo

vé máy bay đi Mỹ giá bao nhiêu

vé máy bay từ texas về việt nam

chuyến bay từ đức về hà nội hôm nay

vé máy bay từ nga về tphcm

chuyến bay từ anh về việt nam

máy bay từ pháp về việt nam

chi phí vé máy bay cho chuyên gia nước ngoài

Abdullah Saif said...

Expecting such type of information in the coming future as it is very necessary as well as illuminative.
december umrah packages 2022

Phil Smith said...

Such an amazing article. I offer desert safari Dubai at affordable prices. The adventure is very interesting and worth visiting. It is one of the best places to visit in Dubai.

Travel lover said...

The first thing that you need to do is open up your code editor and type in the following code: Abu Dhabi city tour

Rony James said...

This is a great service for those who are in need of assistance with their assignments and don't have the time or expertise to do them on their own. Highly recommend! https://www.britishassignmentshelp.co.uk/

wallpaperdig.com said...

Free HD 4K Wallpapers for Mobiles .Once you've downloaded the image, you can set it as your wallpaper or background on your device.

Parker said...

I will always credit you for ability to read. Thank you for your sound advice and tips for reading! God bless you,
logo designer dallas

Advina Jhons said...

La conducción imprudente se refiere a operar un vehículo de manera temeraria o peligrosa, poniendo en riesgo la seguridad de otros conductores y peatones en la carretera.
Charlotte Conducción imprudente

Roman said...

Commercial Contract Disputes Lawyer
The CommonUtils class provides utility methods for common operations, such as calculating the sum of two integers, checking if a string is empty or null, parsing a date string into a Date object, and handling exceptions gracefully. The class's methods include adding an integer to the first integer, checking if a string is empty or null, parsing a date string into a Date object, and handling exceptions gracefully by logging them. The comments provide a brief description of the class and its methods, parameter descriptions, return value explanations, and the purpose of each method. Adjust the comments according to your specific CommonUtils class and its methods. The comments should be adjusted according to the specific CommonUtils class and its methods.

Antony said...

Great and informative post. This is a good blog and I loved the way how the information is quoted in it.
Abogado Federal de Defensa Criminal Maryland

Rachel said...

reckless driving by speed in virginia fine
Automate Amazon's CommonUtils module is a game-changer, streamlining repetitive tasks and enhancing efficiency. Its versatile methods provide a robust set of tools for automation. CommonUtils' error handling mechanisms are well-implemented, making troubleshooting smoother. The well-documented methods make it easy for new and experienced users to navigate and utilize automation functions effectively. The robust exception handling ensures unexpected issues are addressed, minimizing disruptions in automated processes. The developers behind Automate Amazon have excelled in creating CommonUtils, contributing to a reliable and user-friendly automation experience.

Alexander_01 said...

Streamline Amazon automation with CommonUtils, offering a suite of methods tailored for seamless integration. Navigate potential challenges effortlessly using our robust exception-handling mechanisms. Elevate your automated processes, ensuring efficiency and reliability in your Amazon operations with CommonUtils, the essential toolkit for optimizing your workflow on the platform. "Your comment is like a burst of confetti, adding joy to our blog. Each word is a brushstroke on the canvas of conversation, creating a vibrant tapestry of ideas. We eagerly await your next insight, as your contributions light up our digital world. Thanks for being our comment superstar!"violation of a protective order virginia

james anderson said...

Automating Amazon with Selenium WebDriver is made efficient and error-proof by implementing a Common Utilities library. Exception handling and logging functionalities ensure clear error messages, simplifying debugging processes.
New Jersey Reckless Driving

Bennyjo said...

Streamline your Amazon automation with CommonUtils, offering essential methods and handling exceptions effortlessly. Elevate your coding experience by incorporating these efficient tools into your automation scripts, ensuring a seamless and error-resistant process. Simplify your development journey with CommonUtils for Amazon automation success. chapter 7 bankruptcy lawyers near me