Important: The GCConnex decommission will not affect GCCollab or GCWiki. Thank you and happy collaborating!
Difference between revisions of "EODMS Katalon"
Jump to navigation
Jump to search
| Line 1: | Line 1: | ||
| − | + | Types | |
<pre> | <pre> | ||
| + | |||
import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint | import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint | ||
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase | import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase | ||
| Line 9: | Line 10: | ||
import com.kms.katalon.core.checkpoint.CheckpointFactory as CheckpointFactory | import com.kms.katalon.core.checkpoint.CheckpointFactory as CheckpointFactory | ||
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as MobileBuiltInKeywords | import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as MobileBuiltInKeywords | ||
| − | |||
import com.kms.katalon.core.model.FailureHandling as FailureHandling | import com.kms.katalon.core.model.FailureHandling as FailureHandling | ||
import com.kms.katalon.core.testcase.TestCase as TestCase | import com.kms.katalon.core.testcase.TestCase as TestCase | ||
| Line 18: | Line 18: | ||
import com.kms.katalon.core.testobject.TestObject as TestObject | import com.kms.katalon.core.testobject.TestObject as TestObject | ||
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WSBuiltInKeywords | import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WSBuiltInKeywords | ||
| − | import com.kms.katalon.core. | + | import com.kms.katalon.core.webui.driver.DriverFactory as DriverFactory |
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUiBuiltInKeywords | 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.webui.keyword.WebUiBuiltInKeywords as WebUI | ||
| − | import internal.GlobalVariable as | + | 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> | </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.checkpoint.CheckpointFactory.findCheckpoint | ||
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase | import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase | ||
| Line 50: | Line 972: | ||
import com.kms.katalon.core.checkpoint.CheckpointFactory as CheckpointFactory | import com.kms.katalon.core.checkpoint.CheckpointFactory as CheckpointFactory | ||
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as MobileBuiltInKeywords | import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as MobileBuiltInKeywords | ||
| − | |||
import com.kms.katalon.core.model.FailureHandling as FailureHandling | import com.kms.katalon.core.model.FailureHandling as FailureHandling | ||
import com.kms.katalon.core.testcase.TestCase as TestCase | import com.kms.katalon.core.testcase.TestCase as TestCase | ||
| Line 59: | Line 980: | ||
import com.kms.katalon.core.testobject.TestObject as TestObject | import com.kms.katalon.core.testobject.TestObject as TestObject | ||
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WSBuiltInKeywords | import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WSBuiltInKeywords | ||
| − | import com.kms.katalon.core. | + | import com.kms.katalon.core.webui.driver.DriverFactory as DriverFactory |
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUiBuiltInKeywords | 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.webui.keyword.WebUiBuiltInKeywords as WebUI | ||
| − | import | + | 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() | ||
| − | WebUI. | + | // 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> | </pre> | ||
| − | |||
| − | |||
Revision as of 04:57, 15 October 2019
Types
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;
}
}
Script
/**
* 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()
}