Difference between revisions of "EODMS Katalon"

From wiki
Jump to: navigation, search
(Replaced content with "https://github.com/nrcan-eodms-sgdot-rncan/eodms-scene-retriever")
(Tag: Replaced)
 
Line 1: Line 1:
Types
+
https://github.com/nrcan-eodms-sgdot-rncan/eodms-scene-retriever
 
 
<pre>
 
 
 
import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint
 
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase
 
import static com.kms.katalon.core.testdata.TestDataFactory.findTestData
 
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
 
import com.kms.katalon.core.checkpoint.Checkpoint as Checkpoint
 
import com.kms.katalon.core.checkpoint.CheckpointFactory as CheckpointFactory
 
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as MobileBuiltInKeywords
 
import com.kms.katalon.core.model.FailureHandling as FailureHandling
 
import com.kms.katalon.core.testcase.TestCase as TestCase
 
import com.kms.katalon.core.testcase.TestCaseFactory as TestCaseFactory
 
import com.kms.katalon.core.testdata.TestData as TestData
 
import com.kms.katalon.core.testdata.TestDataFactory as TestDataFactory
 
import com.kms.katalon.core.testobject.ObjectRepository as ObjectRepository
 
import com.kms.katalon.core.testobject.TestObject as TestObject
 
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WSBuiltInKeywords
 
import com.kms.katalon.core.webui.driver.DriverFactory as DriverFactory
 
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUiBuiltInKeywords
 
import internal.GlobalVariable as GlobalVariable
 
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
 
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as Mobile
 
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS
 
import com.thoughtworks.selenium.Selenium
 
import org.openqa.selenium.firefox.FirefoxDriver
 
import org.openqa.selenium.WebDriver
 
import org.openqa.selenium.Keys
 
import org.openqa.selenium.StaleElementReferenceException
 
import org.openqa.selenium.WebElement
 
import org.openqa.selenium.interactions.Actions
 
import org.openqa.selenium.support.ui.ExpectedConditions
 
import org.openqa.selenium.support.ui.WebDriverWait
 
import org.openqa.selenium.support.ui.Select
 
import org.openqa.selenium.JavascriptExecutor
 
import org.junit.After
 
import com.thoughtworks.selenium.webdriven.WebDriverBackedSelenium
 
import static org.junit.Assert.*
 
import java.util.regex.Pattern
 
import static org.apache.commons.lang3.StringUtils.join
 
import java.text.SimpleDateFormat
 
import internal.GlobalVariable
 
import MobileBuiltInKeywords as Mobile
 
import WSBuiltInKeywords as WS
 
import WebUiBuiltInKeywords as WebUI
 
 
 
import java.util.HashMap
 
import java.util.UUID
 
 
 
/**
 
* Holds the various search parameters which were entered into the EODMS interface by the user.
 
* Is passed to the search() function to provide parameters for searches.
 
*
 
* @author Kieran Moynihan
 
*/
 
public class SearchParameters {
 
String region;
 
String dateType;
 
String[] dates;
 
String[] selectedSatellites
 
HashMap<String, String> textfieldValues;
 
HashMap<String, Integer> radioSelected;
 
HashMap<String, Integer> checkboxSelected;
 
HashMap<String, String[]> selectboxSelectedOptionsText;
 
 
 
public String getStartDate(){
 
return dates[0]
 
}
 
 
 
public String getEndDate(){
 
return dates[1]
 
}
 
 
 
public void setStartDate(String newStartDate){
 
dates[0] = newStartDate
 
}
 
 
 
public void setEndDate(String newEndDate){
 
dates[1] = newEndDate
 
}
 
 
 
/**
 
*
 
* @param r String Name of Saved AOI region generated with UUID.
 
* @param d String Date type. Search option specifying Past 24 Hours, Any Time, Date Range, Seasonal Dates.
 
* @param dl String[] Dates. List of dates (0 or 2 dates) specified as boundaries of Date Range or Seasonal Dates.
 
* @param ss String[] Selected Satellites. List of satellites/data sources to get products from.
 
* @param tv HashMap<String, String> Text Field Values. List of all values which user had entered into text fields.
 
* @param rs HashMap<String, Integer> Radio buttons selected. Specifications for which radio buttons had been selected.
 
* @param cs HashMap<String, Integer> Check boxes selected. Specifications for which check boxes had been selected.
 
* @param sb HashMap<String, String[]> Select box options. List of each option selected from list of options in each select box.
 
*/
 
public SearchParameters(String r, String d, String[] dl, String[] ss,
 
HashMap<String, String> tv, HashMap<String, Integer> rs,
 
HashMap<String, Integer> cs, HashMap<String, String[]> sb) {
 
this.region = r;
 
this.dateType = d;
 
this.dates = dl;
 
this.selectedSatellites = ss;
 
this.textfieldValues = tv;
 
this.radioSelected = rs;
 
this.checkboxSelected = cs;
 
this.selectboxSelectedOptionsText = sb;
 
}
 
}
 
 
 
/**
 
* Provides functions used for manipulating and navigating the EODMS web page.
 
*
 
* @author Kieran Moynihan, Khang Nguyen
 
*/
 
public class WebBrowsing {
 
// use these if selenium functions are not enough
 
def driver = DriverFactory.getWebDriver()
 
// Actions can help with focusing on and moving to element that might be hidden (need to scroll down a table to find them)
 
Actions actions = new Actions(driver)
 
// JavascriptExecutor can click on elements that are behind other elements by simply executing a click on the element, rather than simulating a user click
 
JavascriptExecutor js = (JavascriptExecutor) driver
 
 
 
private selenium
 
private gui
 
 
 
/**
 
* selClick with default duration 60 seconds
 
*/
 
public void selClick(String key){
 
selClick(key, 60);
 
}
 
 
 
/**
 
* Attempts to click on an element multiple times until timeout occurs
 
*/
 
public void selClick(String key, int duration){
 
for (int second = 0; second < duration; second++) {
 
try {
 
selenium.click(key)
 
break;
 
} catch (Exception except) {
 
// prints the exception and fails on timeout
 
if (second == duration-1) {
 
println except
 
fail('Timeout on click: '+key)
 
}
 
}
 
Thread.sleep(1000);
 
}
 
}
 
 
 
/**
 
* Enters dates into the dates tab.
 
*/
 
public void enterDates(String sDate, String eDate, String dateType) {
 
// ensure in the date options tab
 
selClick("id=Search")
 
selClick("id=tab2")
 
 
 
// row dependent on date search type
 
String tRow = "";
 
// rows correspond to table rows in the list of date options
 
// row 5 contains text fields for DateRange option, not visible unless DateRange selected
 
if (dateType == 'AnyTime') {
 
tRow = '2'
 
} else if (dateType == 'Past24Hours') {
 
tRow = '3'
 
} else if (dateType == 'DateRange') {
 
tRow = "4"
 
} else if (dateType == 'SeasonalDates') {
 
tRow = "6"
 
}
 
// if AnyTime or Past24Hours selected, no further action required after selecting option
 
if (tRow < 4) {
 
selenium.click("//div[@id='panel2']/div/table/tbody/tr["+tRow+"]/td[2]/table/tbody/tr/td/span/label")
 
return;
 
}
 
// get previous end date from date field
 
// convert date YYYY-MM-DD -> YYYYMMDD
 
String pEDate = String.join("", driver.findElementByXPath("//input[@id='"+dateType+"EndDate']").getAttribute("value").split("-"))
 
// if there was a previous end date and the new start date is greater (later) than the previous end date, change the end date first (otherwise start date first)
 
// this is because if you enter a start date that is later than the value in the end date field, an error will pop up and your previously entered start date will be cleared
 
if (!(pEDate == "") && Integer.parseInt(String.join("", sDate.split("-"))) > Integer.parseInt(pEDate)) {
 
// click end date field and enter end date
 
selenium.click("id="+dateType+"EndDate")
 
selenium.type("id="+dateType+"EndDate", eDate)
 
// click date options tab again to remove popup calendar
 
selenium.click("id=tab2")
 
// click start date field and enter start date
 
selenium.click("id="+dateType+"StartDate")
 
selenium.type("id="+dateType+"StartDate", sDate)
 
// click date options tab again to remove popup calendar
 
selenium.click("id=tab2")
 
} else {
 
selenium.click("//div[@id='panel2']/div/table/tbody/tr["+tRow+"]/td[2]/table/tbody/tr/td/span/label")
 
selenium.click("id="+dateType+"StartDate")
 
selenium.type("id="+dateType+"StartDate", sDate)
 
selenium.click("id=tab2")
 
selenium.click("id="+dateType+"EndDate")
 
selenium.type("id="+dateType+"EndDate", eDate)
 
selenium.click("id=tab2")
 
}
 
}
 
 
 
/**
 
* Logs user into EODMS from the main page.
 
*/
 
public void login(){
 
// start login
 
selClick("link=Login")
 
// enter username
 
selenium.click("id=usernameTextBox")
 
selenium.type("id=usernameTextBox", gui.getUsername())
 
// enter  password
 
selenium.click("id=passwordTextBox")
 
selenium.type("id=passwordTextBox", gui.getPassword())
 
// press login button
 
selenium.click("//*[@id='RootDockPanel']/div/div/div[1]/table/tbody/tr/td/div/table/tbody/tr[2]/td/div/div/div/div/table/tbody/tr/td/table/tbody/tr[4]/td/table/tbody/tr[2]/td/div/table/tbody/tr/td[2]/table/tbody/tr[3]/td/table/tbody/tr[2]/td/table/tbody/tr/td[2]/table/tbody/tr/td/table/tbody/tr[1]/td/div/table/tbody/tr/td[2]/table/tbody/tr/td/table/tbody/tr[2]/td/div/div/div/div/div/table/tbody/tr[2]/td[2]/table/tbody/tr/td[2]/div")
 
Thread.sleep(1000);
 
for(int halfsecond = 0; halfsecond <=60; halfsecond++){
 
try {
 
if (selenium.isVisible("link=Login")) {
 
fail('Incorrect Login Information')
 
}
 
} catch (Exception e) {}
 
try {
 
if (selenium.isVisible("link=My Account")) break;
 
} catch (Exception e) {
 
if (halfsecond == 60) {
 
fail('Timeout on login')
 
}
 
Thread.sleep(500)
 
}
 
}
 
selClick("link=Search")
 
}
 
 
 
/**
 
* Gets the search parameters from the EODMS interface.
 
*/
 
public SearchParameters getSearch(){
 
// ensure in search tab
 
selClick("id=Search")
 
// go to location panel
 
selClick("id=tab1")
 
// Open Save Your Area of Interest
 
if (driver.findElementByXPath("//div[@id='panel1']/div/table/tbody/tr[16]/td/table").getAttribute("aria-hidden") == "true") {
 
selClick("link=Save Your Area of Interest")
 
}
 
// Save the Area of Interest as ESR_[UUID]
 
String tempAOI = 'ESR_'+UUID.randomUUID().toString()
 
selClick("//div[@id='panel1']/div/table/tbody/tr[16]/td/table/tbody/tr/td/table/tbody/tr/td[2]/table/tbody/tr/td/input", 5)
 
selenium.type("//div[@id='panel1']/div/table/tbody/tr[16]/td/table/tbody/tr/td/table/tbody/tr/td[2]/table/tbody/tr/td/input", tempAOI)
 
selClick("//div[@id='panel1']/div/table/tbody/tr[16]/td/table/tbody/tr/td/table/tbody/tr/td[3]/div/div")
 
Thread.sleep(500)
 
for (int quartersecond = 0; quartersecond <= 120; quartersecond++){
 
WebElement[] tables = driver.findElementsByXPath('//table[@class="resizableContentPanel"]')
 
boolean exit = false
 
for (WebElement table : tables) {
 
if (table.getAttribute('aria-describedby') == 'saveAOIBoxDescription') {
 
WebElement okBtn = table.findElementByXPath('./tbody/tr[2]/td/table/tbody/tr[2]/td/table/tbody/tr/td[2]/table/tbody/tr/td/div/div/div/div/div/table/tbody/tr[2]/td[2]/table/tbody/tr/td[2]/div')
 
js.executeScript("arguments[0].click()", okBtn)
 
exit = true
 
break;
 
}
 
}
 
if (exit) break;
 
}
 
// go to date options
 
selClick("id=tab2")
 
// list of Date Type buttons (Any Time, Past 24 Hours, Date Range, Seasonal Dates)
 
WebElement[] datetypes = driver.findElementsByXPath("//input[@name='dates']")
 
// Actual dateType selected
 
String dateType = ""
 
// for each dateType button
 
for (int i = 0; i < datetypes.length; i++){
 
WebElement radBut = datetypes[i]
 
// if dateType button is selected
 
if (radBut.isSelected()){
 
// get the id of the button
 
String id = radBut.getAttribute("id")
 
// dateType is the value of the Label associated with this radio button
 
dateType = selenium.getText("//label[@for='"+id+"']")
 
break;
 
}
 
}
 
// start and end dates
 
String[] dates;
 
// if is a dateType that uses date values
 
if (dateType == 'Date Range' || dateType == 'Seasonal Dates') {
 
// Remove spaces from dateType name
 
if (dateType == 'Date Range') {
 
dateType = 'DateRange'
 
} else {
 
dateType = 'SeasonalDates'
 
}
 
// retrieve start and end dates
 
String startDate = driver.findElementByXPath("//input[@id='"+dateType+"StartDate']").getAttribute("value")
 
String endDate = driver.findElementByXPath("//input[@id='"+dateType+"EndDate']").getAttribute("value")
 
// set dates
 
dates = [startDate, endDate];
 
// if is a dateType that doesn't use date values
 
} else {
 
if (dateType == 'Any Time') {
 
dateType = 'AnyTime'
 
} else {
 
dateType = 'Past24Hours'
 
}
 
// set default dates
 
dates = ["", ""];
 
}
 
// Go to Data tab (sensors)
 
selenium.click("id=tab3")
 
 
 
// array of satellite options
 
WebElement[] satOptions = driver.findElementsByXPath("//table[@id='panel3']/tbody/tr/td/div/div/div/div/table/tbody/tr[2]/td/div/div[2]/div/div/div/div/div")
 
 
 
// holds satellite option names of satellites that are checked
 
String[] satList = new String[satOptions.length];
 
 
 
// for each satellite option in satOptions, if the option is checked, add the name of the option to satList
 
int satListCount = 0;
 
for (int i = 0; i < satOptions.length; i++) {
 
if (!(satOptions[i].getAttribute("aria-label").endsWith("Not Checked")) && !(satOptions[i].getAttribute("aria-label").endsWith("Partially Checked"))) {
 
satList[i] = driver.findElementByXPath("//div[@id='"+satOptions[i].getAttribute("id")+"']/table/tbody/tr/td[4]/table/tbody/tr[1]/td/table/tbody/tr/td[1]/div").getAttribute("innerText");
 
satListCount++;
 
} else {
 
satList[i] = ""
 
}
 
}
 
 
 
// satList with "" values removed
 
String[] selectedSatellites = new String[satListCount];
 
satListCount = 0;
 
for (int i = 0; i < satList.length; i++) {
 
if (satList[i] != "") {
 
selectedSatellites[satListCount] = satList[i];
 
satListCount++;
 
}
 
}
 
// Go to Data options tab
 
selenium.click("id=tab4")
 
// retrieve all parameter web elements from the options tab
 
WebElement optionsPanel = driver.findElementByXPath("//div[@id='panel4']")
 
WebElement[] textfields = optionsPanel.findElementsByXPath(".//input[@type='text']")
 
WebElement[] radiobuttons = optionsPanel.findElementsByXPath(".//input[@type='radio']")
 
WebElement[] checkboxes = optionsPanel.findElementsByXPath(".//input[@type='checkbox']")
 
WebElement[] selectboxes = optionsPanel.findElementsByXPath(".//select")
 
 
 
// hash maps with keys of identifiers and values of values for each (set of) element(s)
 
HashMap<String, String> textfieldValues = new HashMap<String, String>();
 
HashMap<String, Integer> radioSelected = new HashMap<String, Integer>();
 
HashMap<String, Integer> checkboxSelected = new HashMap<String, Integer>();
 
HashMap<String, String[]> selectboxSelectedOptionsText = new HashMap<String, String[]>();
 
 
 
// for each text field
 
for (WebElement textfield : textfields) {
 
// if the user entered text in the field
 
if (textfield.getAttribute("title") != "") {
 
// add the string to hash map with title of text field as key
 
textfieldValues.put(textfield.getAttribute("title"), textfield.getAttribute("value"))
 
}
 
}
 
// for each radio button
 
for (WebElement radiobutton : radiobuttons) {
 
// if the radio button was selected by the user
 
if (radiobutton.isSelected()){
 
String category = radiobutton.findElementByXPath("../../../../../../table").getAttribute("title")
 
WebElement[] allButtons = radiobutton.findElementsByXPath("../../../td")
 
int position = 0
 
for (int i = 0; i < allButtons.length; i++){
 
if (allButtons[i].findElementByXPath("./span/input").getAttribute("id") == radiobutton.getAttribute("id")) {
 
position = i+1;
 
break;
 
}
 
}
 
// add the index in the group of the selected radio button to the hash map with the name of the group of radio buttons as the key
 
radioSelected.put(category, position)
 
}
 
}
 
// for each check box
 
for (WebElement checkbox : checkboxes) {
 
// if the check box was selected by the user
 
if (checkbox.isSelected()){
 
String category = checkbox.findElementByXPath("../../../../../../table").getAttribute("title")
 
WebElement[] allButtons = checkbox.findElementsByXPath("../../../td")
 
int position = 0
 
for (int i = 0; i < allButtons.length; i++){
 
if (allButtons[i].findElementByXPath("./span/input").getAttribute("id") == checkbox.getAttribute("id")) {
 
position = i+1;
 
break;
 
}
 
}
 
// add the index in the group of the selected check box to the hash map with the name of the group of check boxes as the key
 
checkboxSelected.put(category, position)
 
}
 
}
 
// for each select box
 
for (WebElement selectbox : selectboxes) {
 
WebElement[] selOpt = new Select(selectbox).getAllSelectedOptions();
 
String[] options = new String[selOpt.length]
 
for (int i = 0; i < selOpt.length; i++) {
 
options[i] = selOpt[i].getText()
 
}
 
// add the list of options selected within the select box to the hash map with the name of the hash map as the  key
 
selectboxSelectedOptionsText.put(selectbox.getAttribute("title"), options)
 
}
 
// return the SearchParameters
 
return new SearchParameters(tempAOI, dateType, dates, selectedSatellites, textfieldValues, radioSelected, checkboxSelected, selectboxSelectedOptionsText)
 
}
 
 
 
/**
 
* Enters the search parameters into the EODMS interface.
 
*/
 
public void search(SearchParameters SearchDetails){
 
// wait for new page to load
 
for (int quartersecond = 0; quartersecond < 60 ; quartersecond++) {
 
try {
 
if (selenium.isVisible("link=Use a Saved Area of Interest")) break;
 
} catch (Exception e) { if (quartersecond == 60) fail("Can't see Saved Area of Interest link")}
 
Thread.sleep(250);
 
}
 
// go to saved AOIs
 
if (driver.findElementByXPath("//div[@id='panel1']/div/table/tbody/tr[12]/td/table").getAttribute("aria-hidden") == "true") {
 
selClick("link=Use a Saved Area of Interest")
 
}
 
WebElement[] aois = driver.findElementsByXPath("//div[@id='panel1']/div/table/tbody/tr[12]/td/table/tbody/tr/td/table/tbody/tr/td[1]/a")
 
for (WebElement aoi : aois){
 
if (aoi.getAttribute('title') == SearchDetails.getRegion()){
 
js.executeScript("arguments[0].click()", aoi)
 
break;
 
}
 
}
 
// go to date options
 
selenium.click("id=tab2")
 
// get dateType, start and end dates
 
String dateType = SearchDetails.getDateType();
 
String startDate = SearchDetails.getStartDate();
 
String endDate = SearchDetails.getEndDate();
 
if (dateType == 'AnyTime') {
 
// click Any Time option
 
selenium.click("//div[@id='panel2']/div/table/tbody/tr[2]/td[2]/table/tbody/tr/td/span/label")
 
} else {
 
// If SeasonalDates or DateRange, enter bounding dates
 
// if SeasonalDates or DateRange but no dates were entered, fail
 
if(startDate != "" && endDate != ""){
 
enterDates(startDate, endDate, dateType)
 
// catch is AnyTime
 
}else{
 
fail('Date Option is set to '+dateType+' but no dates were set.')
 
}
 
}
 
// Go to Data tab (sensors)
 
selenium.click("id=tab3")
 
// select the specified satellites
 
// get satellites to select from search details
 
String[] selectedSatellites = SearchDetails.getSelectedSatellites()
 
 
 
// list of satellite/data source options
 
WebElement[] satOptions = driver.findElementsByXPath("//table[@id='panel3']/tbody/tr/td/div/div/div/div/table/tbody/tr[2]/td/div/div[2]/div/div/div/div/div")
 
 
 
// holds xpath values for satellites that are selected
 
String[] satelliteButtons = new String[selectedSatellites.length];
 
 
 
// get and save xpath values into satelliteButtons
 
for (int i = 0; i < satOptions.length; i++) {
 
String satName = driver.findElementByXPath("//div[@id='"+satOptions[i].getAttribute("id")+"']/table/tbody/tr/td[4]/table/tbody/tr[1]/td/table/tbody/tr/td[1]/div").getAttribute("innerText");
 
for (int j = 0; j  < selectedSatellites.length; j++) {
 
if (selectedSatellites[j] == satName){
 
satelliteButtons[j] = "//div[@id='"+satOptions[i].getAttribute("id")+"']/table/tbody/tr/td[2]/img"
 
}
 
}
 
}
 
// for each satellite to select
 
for (String sat : satelliteButtons) {
 
for (int decisecond = 0; true; decisecond++){
 
// try to click the satellite until it works
 
try {
 
// unless it is already selected
 
if (!(driver.findElementByXPath(sat).getAttribute("title") == "This node and all children nodes are selected.")){
 
selenium.click(sat)
 
}
 
break;
 
} catch (Exception e) {
 
if (decisecond >= 100) {
 
println e
 
fail('Timeout looking for satellite buttons.')
 
}
 
}
 
Thread.sleep(100)
 
}
 
 
 
}
 
// Go to Data options tab
 
selenium.click("id=tab4")
 
// Get search parameters from SearchDetails
 
HashMap<String, String> tfv = SearchDetails.getTextfieldValues()
 
HashMap<String, Integer> rbs = SearchDetails.getRadioSelected()
 
HashMap<String, Integer> cbs = SearchDetails.getCheckboxSelected()
 
HashMap<String, String[]> sbo = SearchDetails.getSelectboxSelectedOptionsText()
 
 
 
// wait for Date Options to load
 
for (int decisecond = 0; true; decisecond++){
 
try {
 
if (selenium.isVisible("//div[@id='panel4']/table/tbody/tr/td/table/tbody/tr/td/div/div/table/tbody/tr[1]/td/div")) break;
 
} catch (Exception e){
 
if (decisecond >= 100) {
 
println e
 
fail('Timeout waiting for Data Options.')
 
}
 
}
 
Thread.sleep(100);
 
}
 
 
 
for (int quartersecond = 0; true; quartersecond++) {
 
try {
 
// get the list of text fields on page
 
WebElement[] textFields = driver.findElementsByXPath("//input[@type='text']")
 
// for each text field in search parameters
 
for (String textFieldTitle : tfv.keySet()) {
 
// for each text field on page
 
for (WebElement textField : textFields) {
 
// if the text field on the page has the same title as from search parameters
 
if (textField.getAttribute("title") == textFieldTitle) {
 
// type the gathered value into the text field
 
actions.moveToElement(textField)
 
actions.click()
 
actions.sendKeys(tfv.get(textFieldTitle))
 
}
 
}
 
}
 
actions.build().perform()
 
break;
 
} catch (Exception e) {
 
if (quartersecond >= 12) {
 
println e;
 
fail('Timeout waiting to enter text field parameters.');
 
}
 
Thread.sleep(250)
 
}
 
}
 
 
 
for (int quartersecond = 0; true; quartersecond++) {
 
try {
 
// for each selected radio button from search parameters
 
for (String radioButtonCategory : rbs.keySet()) {
 
// click on it
 
actions.moveToElement(driver.findElementByXPath("//table[@title='"+radioButtonCategory+"']/tbody/tr/td["+rbs.get(radioButtonCategory).toString()+"]/span/input"))
 
actions.click()
 
}
 
actions.build().perform()
 
break;
 
} catch (Exception e) {
 
if (quartersecond >= 10) {
 
println e;
 
fail('Timeout waiting to enter radio button parameters.');
 
}
 
Thread.sleep(250)
 
}
 
}
 
 
 
for (int quartersecond = 0; true; quartersecond++) {
 
try {
 
// for each selected check box from search parameters
 
for (String checkboxCategory : cbs.keySet()) {
 
// click on it
 
actions.moveToElement(driver.findElementByXPath("//table[@title='"+checkboxCategory+"']/tbody/tr/td["+cbs.get(checkboxCategory).toString()+"]/span/input"))
 
actions.click()
 
}
 
actions.build().perform()
 
break;
 
} catch (Exception e) {
 
if (quartersecond >= 10) {
 
println e;
 
fail('Timeout waiting to enter checkbox parameters.');
 
}
 
Thread.sleep(250)
 
}
 
}
 
 
 
for (int quartersecond = 0; true; quartersecond++) {
 
try {
 
// get the list of selectboxes current on the page
 
WebElement[] selectBoxes = driver.findElementsByXPath("//select")
 
// for each select box title that was gathered from search parameters
 
for (String selectboxTitle : sbo.keySet()) {
 
// for each select box on page
 
for (WebElement selectBox : selectBoxes) {
 
// if the select box on the page has the same title as we have, it should paramaterized
 
if (selectBox.getAttribute("title") == selectboxTitle) {
 
// get options selected from search parameters
 
String[] selectedOptions = sbo.get(selectboxTitle)
 
// if at least one option was selected
 
if (selectedOptions.length > 0) {
 
Select sel = new Select(selectBox)
 
// deselect all previously selected options ("Any"/default option normally)
 
sel.deselectAll()
 
// select each option that was gathered from searhc parameters
 
for (String option : selectedOptions){
 
sel.selectByVisibleText(option)
 
}
 
}
 
}
 
}
 
}
 
break;
 
} catch (Exception e) {
 
if (quartersecond >= 10) {
 
println e;
 
fail('Timeout waiting to enter selectbox parameters.');
 
}
 
Thread.sleep(250)
 
}
 
}
 
 
 
// go to submit search tab
 
selenium.click("id=tab5")
 
// specify the number of products per collection to the max (500)
 
selenium.click("id=numSearchResults")
 
selenium.click("//option[@value='500']")
 
}
 
 
 
/**
 
* Gets the number of products in the search from the search page.
 
*/
 
public String searchNumber(){
 
// ensure in Search, Submit Search tab
 
selClick("id=Search")
 
selClick("id=tab5")
 
// run the Get total result count link
 
selClick("link=Get total result count")
 
Thread.sleep(1000);
 
// wait for count to finish
 
for (int second = 0; true; second++) {
 
try {
 
if (selenium.isVisible("//img[@alt='Search Complete']")) break;
 
} catch (Exception e) {
 
if (second == 300) {
 
fail('Timeout waiting for product count.')
 
}
 
}
 
Thread.sleep(1000);
 
}
 
// get count from the popup
 
String tmp = selenium.getText("//div/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td/div/div[2]").split("\\s+")[1]
 
// close the popup
 
selClick("xpath=(.//*[normalize-space(text()) and normalize-space(.)='Loading'])[1]/following::img[14]")
 
return tmp
 
}
 
 
 
/**
 
* Default value override of order()
 
* - Default max scenes per cart is 50
 
*/
 
public String[] order (String sDate, String eDate) {
 
order(sDate, eDate, 50)
 
}
 
 
 
/**
 
* Manages the process of adding products/scenes to the EODMS cart
 
*/
 
public String[] order (String sDate, String eDate, int maxScenes) {
 
// whether cart is full/maxScenes is reached
 
boolean full = false;
 
// max capacity of Cart
 
int maxCart = -1;
 
// date of last product looked at
 
String lastDate = "";
 
// XPath to table holding product lists
 
String frame = "//div[@id='InitialSearchPanel']/table/tbody";
 
// current page that is being looked at
 
int pagenum = 0;
 
// lowest product number on page
 
int lowCount = -1;
 
// highest product number on page
 
int highCount = -1;
 
// total number of products on all pages
 
int maxCount = -1;
 
// number of products that have been added to the cart
 
int productCount = 0;
 
// number of scenes that have been added to the cart
 
int currentCart = 0;
 
 
 
// ensure in search tab
 
selClick("id=Search")
 
Thread.sleep(500);
 
// if a start and end date were provided
 
if (!(sDate == "" && eDate == "")) {
 
String dateType = ""
 
// go to date options tab
 
selenium.click("id=tab2")
 
// wait and see whether DateRange or SeasonalDates are being used
 
for (int second = 0;second <= 60; second++) {
 
try {
 
if (selenium.isVisible("id=DateRangeStartDate")) {
 
dateType = 'DateRange'
 
break;
 
} else if (selenium.isVisible("id=SeasonalDatesStartDate")) {
 
dateType = 'SeasonalDates'
 
break;
 
}
 
} catch (Exception e) {}
 
Thread.sleep(1000);
 
}
 
// enter the passed dates
 
enterDates(sDate, eDate, dateType)
 
}
 
// go to Submit search tab
 
selClick("id=tab5")
 
// press search button
 
selClick("//div[@id='panel5']/div/table/tbody/tr[6]/td[2]/div/div/div/div/div/table/tbody/tr[2]/td[2]/table/tbody/tr/td[2]/div")
 
// wait for results to load
 
for (int second = 0;second <= 60; second++) {
 
try {
 
if (selenium.isVisible(frame+"/tr[3]/td/table/tbody/tr/td[2]/table/tbody/tr/td[7]/div")) break;
 
} catch (Exception e) {}
 
Thread.sleep(1000);
 
}
 
// get number of pages
 
int pages = Integer.parseInt(selenium.getText(frame+"/tr[3]/td/table/tbody/tr/td[2]/table/tbody/tr/td[7]/div"))
 
// start adding products to cart until a limit is reached
 
while (true) {
 
try {
 
// update page number
 
pagenum++;
 
// get the string containing the low, high, and max product counts
 
String[] scenesInPage = selenium.getText(frame+"/tr[3]/td/table/tbody/tr/td[1]/div").split("\\s+")
 
// get low and high product counts
 
lowCount = Integer.parseInt(scenesInPage[1])
 
highCount = Integer.parseInt(scenesInPage[3])
 
// if no max count has been set yet
 
if (maxCount == -1) {
 
// if there is a max count value in string
 
if (pages > 1) {
 
maxCount = Integer.parseInt(scenesInPage[5])
 
// if there is only one page, there won't be a max count value, only low to high (max count is same as high)
 
} else {
 
maxCount = highCount
 
}
 
}
 
// for each product in the page
 
for (int currentScene = 0; currentScene < ((highCount-lowCount)+1); currentScene++){
 
// update product count
 
productCount++;
 
// row in the table that product is located in
 
String productRow = Integer.toString(currentScene+3)
 
// wait for product to be visible
 
for (int second = 0;second <= 240; second++) {
 
try {
 
if (selenium.isVisible(frame+"/tr[2]/td/div/div/div/div[2]/table/tbody/tr["+productRow+"]/td[2]/div/span/input")) break;
 
} catch (Exception e) {}
 
Thread.sleep(250);
 
}
 
WebElement elem;
 
// get the checkbox element and date of the product
 
for (int i = 0; i < 100; i++){
 
try {
 
elem = driver.findElementByXPath(frame+"/tr[2]/td/div/div/div/div[2]/table/tbody/tr["+productRow+"]/td[2]/div/span/input")
 
lastDate = driver.findElementByXPath(frame+"/tr[2]/td/div/div/div/div[2]/table/tbody/tr["+productRow+"]/td[4]/div").getText().split("\\s+")[0]
 
break;
 
} catch (StaleElementReferenceException e) {
 
Thread.sleep(100)
 
continue;
 
}
 
}
 
// if the element has not already been added to the cart
 
if (!driver.findElementByXPath(frame+"/tr[2]/td/div/div/div/div[2]/table/tbody/tr["+productRow+"]/td[2]/div/span/input").isSelected()) {
 
// try to add the element to the cart
 
selClick(frame+"/tr[2]/td/div/div/div/div[2]/table/tbody/tr["+productRow+"]/td[2]/div/span/input")
 
boolean skip = false
 
// wait for a popup to load
 
for (int quartersecond = 0;quartersecond <= 300; quartersecond++) {
 
try {
 
// if the add to cart popup appears
 
if (selenium.isVisible("xpath=(.//*[normalize-space(text()) and normalize-space(.)='Add to Cart'])[1]/preceding::input[1]")) break;
 
} catch (Exception e) {}
 
try{
 
// if a popup indicating that the product has been ordered previously
 
/**
 
// re-order the product
 
// Note: if this is re-enabled, then there will be duplicates requested. The current system starts a new search
 
// from the end-date of the most recently looked at product. If there were multiple products on the same date,
 
// those same objects will re-appear in the search for the next collection of products. This should be fixed
 
selenium.click("//div[(text() = 'Re-order' or . = 'Re-order')]")
 
*/
 
// do not re-order previously ordered products
 
selenium.click("//div[(text() = 'Do not re-order' or . = 'Do not re-order')]")
 
// skip (remove this if previously ordered products will be ordered again)
 
skip = true
 
break;
 
} catch (Exception e){}
 
try{
 
// if a popup indicating that the product is not available in the archive
 
// close the popup
 
WebElement[] tables = driver.findElementsByXPath('//table[@class="resizableContentPanel"]')
 
boolean exit = false
 
for (WebElement table : tables) {
 
if (table.getAttribute('aria-label') == 'Order Imagery Product') {
 
WebElement closeBtn = table.findElementByXPath('./tbody/tr[2]/td/table/tbody/tr[2]/td/table/tbody/tr/td[3]/table/tbody/tr/td/div/div/div/div/div/table/tbody/tr[2]/td[2]/table/tbody/tr/td[2]/div')
 
js.executeScript("arguments[0].click()", closeBtn)
 
// and skip to the next product
 
skip = true
 
exit = true
 
break;
 
}
 
}
 
if (exit) break;
 
} catch (Exception e){println e}
 
Thread.sleep(250);
 
}
 
// if the product reached the add to cart popup
 
if (skip == false) {
 
// get the cart limits (current number in cart and max number in cart)
 
String[] cartLimits = selenium.getText("//div[@class='addToCartLimitPanel']/div").split("\\s+")
 
currentCart = Integer.parseInt(cartLimits[0])
 
// update maxCart if no value yet
 
if (maxCart == -1) {
 
maxCart = Integer.parseInt(cartLimits[4])
 
// cart max is the lowest of maxCart (max allowed by EODMS) and maxScenes (max passed by program)
 
maxCart = (maxCart < maxScenes) ? maxCart : maxScenes
 
}
 
// get all checkboxes for scenes in product
 
WebElement[] scanProducts = driver.findElementsByXPath("//table[@class='basicTable']/tbody/tr/td[6]/span/input")
 
if (currentCart+scanProducts.length > maxCart) {
 
// if not all scenes will fit in the cart
 
// mark as cart being full
 
full = true
 
} else {
 
// if all scenes will fit
 
// click each scene checkbox
 
for (WebElement scanProduct : scanProducts) {
 
actions.moveToElement(scanProduct)
 
actions.click()
 
}
 
actions.build().perform()
 
}
 
// click button to update cart
 
selenium.click("//td[3]/table/tbody/tr/td/div/div/div/div/div/table/tbody/tr[2]/td[2]/table/tbody/tr/td[2]/div")
 
}
 
}
 
// if the cart is full, stop adding
 
if (full == true) break;
 
}
 
// if the last page has been completed or cart is full, stop adding
 
if (pagenum >= pages || full == true) break;
 
// otherwise, go to the next page
 
WebElement elem = driver.findElementByXPath(frame+"/tr[3]/td/table/tbody/tr/td[2]/table/tbody/tr/td[8]/div")
 
// JavascriptExecutor is used here because sometimes next-page button is hidden behind an invisible element
 
js.executeScript("arguments[0].click()", elem)
 
} catch (Exception e) {
 
println e
 
fail('Error in ordering scenes')
 
}
 
}
 
// return informative string array to main (used for determining future carts)
 
String[] output = [lastDate, productCount.toString(), full.toString(), currentCart.toString()]
 
return output;
 
}
 
 
 
/**
 
* Submits an order once the cart is full (according to maxCart) or all products are collected
 
*/
 
public void finalOrder(){
 
// go to the cart page
 
selClick("//div[@id='Cart']/div/div/div/div/div/table/tbody/tr[2]/td[2]")
 
Thread.sleep(1000);
 
// click on the Submit Satellite Product Order button
 
selClick("//tr[3]/td/table/tbody/tr/td/div/div/div/div/div/table/tbody/tr[2]/td[2]/table/tbody/tr/td[2]/div")
 
// click on the Order button
 
Thread.sleep(1000);
 
for (int quartersecond = 0; quartersecond <= 240; quartersecond++) {
 
try {
 
WebElement elem = driver.findElementByXPath("//div[@title='Order']/div/div/div/div/table/tbody/tr[2]/td[2]")
 
js.executeScript("arguments[0].click()", elem)
 
break;
 
} catch (Exception e){
 
if (quartersecond == 240) {
 
fail('Timed out trying to click Order button.')
 
}
 
}
 
Thread.sleep(250)
 
}
 
// click on the OK button after order appears
 
for (int quartersecond = 0; quartersecond <= 240; quartersecond++) {
 
try {
 
WebElement elem = driver.findElementByXPath("//div[@title='OK']/div/div/div/div/table/tbody/tr[2]/td[2]/table")
 
js.executeScript("arguments[0].click()", elem)
 
break;
 
} catch (Exception e) {
 
if (quartersecond == 240) {
 
fail('Timed out waiting to press OK on order checkout.')
 
}
 
}
 
Thread.sleep(250);
 
}
 
Thread.sleep(3000);
 
}
 
 
public boolean clearAOI(String region){
 
try{
 
selClick("id=Search")
 
selClick("id=tab1")
 
WebElement aoiTable = driver.findElementByXPath("//div[@id='panel1']/div/table/tbody/tr[12]/td/table")
 
if (aoiTable.getAttribute("aria-hidden") == "true") {
 
selClick("link=Use a Saved Area of Interest")
 
}
 
WebElement[] aois = aoiTable.findElementsByXPath("./tbody/tr/td/table/tbody/tr")
 
for (WebElement aoi : aois) {
 
if (aoi.findElementByXPath("./td[1]/a").getAttribute("title") == region) {
 
js.executeScript("arguments[0].click()", aoi.findElementByXPath("./td[2]/a"))
 
WebElement[] tables = driver.findElementsByXPath('//table[@class="resizableContentPanel"]')
 
for (int quartersecond = 0; quartersecond <= 120; quartersecond++){
 
boolean exit = false
 
for (WebElement table : tables) {
 
if (table.getAttribute('aria-label') == 'Are you sure you want to delete this Saved AOI?') {
 
WebElement okBtn = table.findElementByXPath('./tbody/tr[2]/td/table/tbody/tr[2]/td/table/tbody/tr/td[2]/table/tbody/tr/td/div/div/div/div/div/table/tbody/tr[2]/td[2]/table/tbody/tr/td[2]/div')
 
js.executeScript("arguments[0].click()", okBtn)
 
break;
 
}
 
}
 
return true
 
}
 
}
 
}
 
 
} catch (Exception e) {
 
return false
 
}
 
}
 
 
 
/**
 
* Logs user out of EODMS
 
*/
 
public void logout(){
 
selClick("id=gwt-uid-2")
 
selClick("id=gwt-uid-6")
 
for (int second = 0;second <= 60; second++) {
 
try {
 
if (selenium.isVisible("link=Login")) break;
 
} catch (Exception e) {}
 
Thread.sleep(1000);
 
}
 
Thread.sleep(1000);
 
}
 
 
 
//reset selenium
 
public void selen(WebDriverBackedSelenium selenium){
 
this.selenium = selenium;
 
}
 
 
 
public WebBrowsing(WebDriverBackedSelenium selenium, StartGUI gui){
 
this.selenium = selenium;
 
this.gui = gui;
 
}
 
}
 
</pre>
 
 
 
Script
 
<pre>
 
 
 
/**
 
* Main control for EODMS Scene Retriever.
 
*
 
* Takes user input for start of run and controls WebBrowsing functions.
 
*
 
* @author Kieran Moynihan, Khang Nguyen
 
*/
 
 
 
import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint
 
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase
 
import static com.kms.katalon.core.testdata.TestDataFactory.findTestData
 
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
 
import com.kms.katalon.core.checkpoint.Checkpoint as Checkpoint
 
import com.kms.katalon.core.checkpoint.CheckpointFactory as CheckpointFactory
 
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as MobileBuiltInKeywords
 
import com.kms.katalon.core.model.FailureHandling as FailureHandling
 
import com.kms.katalon.core.testcase.TestCase as TestCase
 
import com.kms.katalon.core.testcase.TestCaseFactory as TestCaseFactory
 
import com.kms.katalon.core.testdata.TestData as TestData
 
import com.kms.katalon.core.testdata.TestDataFactory as TestDataFactory
 
import com.kms.katalon.core.testobject.ObjectRepository as ObjectRepository
 
import com.kms.katalon.core.testobject.TestObject as TestObject
 
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WSBuiltInKeywords
 
import com.kms.katalon.core.webui.driver.DriverFactory as DriverFactory
 
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUiBuiltInKeywords
 
import internal.GlobalVariable as GlobalVariable
 
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
 
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as Mobile
 
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS
 
import org.openqa.selenium.WebDriver
 
import org.openqa.selenium.WebElement
 
import org.openqa.selenium.JavascriptExecutor
 
import com.thoughtworks.selenium.webdriven.WebDriverBackedSelenium
 
import static org.junit.Assert.*
 
import java.util.regex.Pattern
 
import static org.apache.commons.lang3.StringUtils.join
 
import java.text.SimpleDateFormat
 
 
 
// launch startGUI
 
// StartGUI provides two input fields for user to enter a username and password for EODMS
 
StartGUI gui = new StartGUI();
 
// wait for user to finish entering login
 
while(gui.done() == false){
 
Thread.sleep(250)
 
}
 
gui.dispose()
 
 
 
// open browser and go to URL
 
WebUI.openBrowser('https://www.eodms-sgdot.nrcan-rncan.gc.ca/index_en.jsp')
 
def driver = DriverFactory.getWebDriver()
 
String baseUrl = "https://www.eodms-sgdot.nrcan-rncan.gc.ca/index_en.jsp"
 
selenium = new WebDriverBackedSelenium(driver, baseUrl)
 
selenium.open("https://www.eodms-sgdot.nrcan-rncan.gc.ca/index_en.jsp")
 
WebBrowsing web = new WebBrowsing(selenium, gui);
 
// select the frame containing JavaScript for EODMS
 
selenium.selectFrame("index=0")
 
// wait for login button to load with the page
 
for (int quartersecond = 0;; quartersecond++) {
 
if (quartersecond >= 240) fail("timeout");
 
try { if (selenium.isVisible("link=Login")) break; } catch (Exception e) {}
 
Thread.sleep(250);
 
}
 
 
 
//num will be the number of scans returned by the search
 
int num;
 
 
 
SearchParameters SearchDetails;
 
 
 
try{
 
//log the user into EODMS using the provided login information
 
web.login();
 
 
//wait for the user to press the start button on the WaitGUI
 
//the user is to enter the search parameters into the EODMS interface and then press start
 
//This tool will read the webelements after user presses start in order to determine which options were selected
 
WaitGUI gui2 = new WaitGUI();
 
while (gui2.done() == false){
 
Thread.sleep(250)
 
}
 
gui2.dispose()
 
 
//get search parameters from EODMS interface
 
SearchDetails = web.getSearch();
 
dateType = SearchDetails.getDateType()
 
startDate = SearchDetails.getStartDate()
 
endDate = SearchDetails.getEndDate()
 
 
//gets the number of products returned by the search
 
println 'Getting number of scans...'
 
num = Integer.parseInt(web.searchNumber());
 
// List of years, used for separated SeasonalDates queries
 
int[] yearList;
 
// Maximum number of scenes to place in cart
 
// Once this number of scenes is reached, the cart will be ordered
 
// and a new cart will be filled.
 
int MAXSCENES = 50;
 
// maxScenes is reset to MAXSCENES for each loop of cart filling
 
int maxScenes = MAXSCENES;
 
// Separated DateRange and SeasonalDates operations as SeasonalDates splits the dates entered into years and runs separately
 
// This is necessary as the endDate must be decreased incrementally as carts are filled, and doing so with seasonal dates will affect
 
// all other years to be searched.
 
// ex. 2014-04-01 -> 2016-09-30 vs. 2014-04-01 -> 2016-05-15 (in years 2014 and 2015, the search will only run to YYYY-05-15)
 
if (dateType == 'SeasonalDates') {
 
// get start and end years from date strings
 
int startYear = Integer.parseInt(startDate.substring(0, 4))
 
int endYear = Integer.parseInt(endDate.substring(0, 4))
 
// determine the year gap and make a list of years
 
int yearGap = endYear-startYear
 
yearList = new int[(yearGap)+1]
 
yearList[0] = startYear
 
for (int i = 1; i < yearGap+1; i++) {
 
yearList[i] = startYear+i;
 
}
 
// for each year, run the search over the specified range
 
for (int year : yearList) {
 
// create year string for the current year
 
sDate = year.toString()+startDate.substring(4)
 
eDate = year.toString()+endDate.substring(4)
 
// go to the search tab
 
for (int second = 0;second <= 60; second++) {
 
try {
 
selenium.click("id=Search")
 
break;
 
} catch (Exception e) {}
 
Thread.sleep(1000);
 
}
 
Thread.sleep(250);
 
// update the search dates to the current year
 
web.enterDates(sDate, eDate, dateType);
 
SearchDetails.setStartDate(sDate);
 
SearchDetails.setEndDate(eDate);
 
// get the number of products in the current year
 
yearNum = Integer.parseInt(web.searchNumber());
 
// if there are products for the year, get them (this is the same as dateRange)
 
if (yearNum > 0) {
 
while (true) {
 
println 'Adding scans to cart...'
 
web.logout()
 
web.login()
 
web.search(SearchDetails)
 
// return from web.order:
 
// [Last date that was seen from order (end next search here),
 
// number of products carted,
 
// whether the cart was full,
 
// number of scenes carted (can be multiple scenes per product)]
 
String[] orderOut = web.order(sDate, eDate, maxScenes)
 
// new end date
 
eDate = orderOut[0]
 
SearchDetails.setEndDate(eDate)
 
// number of products remaining in year
 
yearNum -= Integer.parseInt(orderOut[1])
 
// number of scenes remaining before cart full
 
maxScenes -= Integer.parseInt(orderOut[3])
 
// if cart was full, assume there are more products
 
if (Boolean.valueOf(orderOut[2]) == true) {
 
println 'There are more products'
 
// submit order
 
web.finalOrder()
 
// reset maxScenes
 
maxScenes = MAXSCENES
 
// if there are no more products in the year, finished searching year
 
} else if (yearNum <= 0) {
 
break;
 
}
 
}
 
}
 
}
 
} else {
 
while (true) {
 
println 'Adding scans to cart...'
 
web.logout()
 
web.login()
 
web.search(SearchDetails)
 
// return from web.order:
 
// [Last date that was seen from order (end next search here),
 
// number of products carted,
 
// whether the cart was full,
 
// number of scenes carted (can be multiple scenes per product)]
 
String[] orderOut = web.order(startDate, endDate, maxScenes)
 
// new end date
 
endDate = orderOut[0]
 
SearchDetails.setEndDate(endDate)
 
// number of products remaining
 
num -= Integer.parseInt(orderOut[1])
 
// number of scenes remaining before cart full
 
maxScenes -= Integer.parseInt(orderOut[3])
 
// if cart was full, assume there are more products
 
if (Boolean.valueOf(orderOut[2]) == true) {
 
println 'There are more products'
 
// submit order
 
web.finalOrder()
 
// reset maxScenes
 
maxScenes = MAXSCENES
 
// if there are no more products, finished searching
 
} else if (num <= 0) {
 
break;
 
}
 
}
 
}
 
// last submission
 
println 'Got all products'
 
web.finalOrder();
 
} catch (Exception e) {
 
println e
 
} finally {
 
if (!web.clearAOI(SearchDetails.getRegion())) {
 
web.logout()
 
web.login()
 
web.clearAOI(SearchDetails.getRegion())
 
}
 
driver.quit()
 
}
 
</pre>
 

Latest revision as of 13:22, 3 November 2019