Changes

Jump to: navigation, search

EODMS Katalon

45,840 bytes removed, 13:22, 3 November 2019
Replaced content with "https://github.com/nrcan-eodms-sgdot-rncan/eodms-scene-retriever"
Types <pre> import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpointimport static com.kms.katalon.core.testcase.TestCaseFactory.findTestCaseimport static com.kms.katalon.core.testdata.TestDataFactory.findTestDataimport static com.kms.katalon.core.testobject.ObjectRepository.findTestObjectimport com.kms.katalon.core.checkpoint.Checkpoint as Checkpointimport com.kms.katalon.core.checkpoint.CheckpointFactory as CheckpointFactoryimport com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as MobileBuiltInKeywordsimport com.kms.katalon.core.model.FailureHandling as FailureHandlingimport com.kms.katalon.core.testcase.TestCase as TestCaseimport com.kms.katalon.core.testcase.TestCaseFactory as TestCaseFactoryimport com.kms.katalon.core.testdata.TestData as TestDataimport com.kms.katalon.core.testdata.TestDataFactory as TestDataFactoryimport com.kms.katalon.core.testobject.ObjectRepository as ObjectRepositoryimport com.kms.katalon.core.testobject.TestObject as TestObjectimport com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WSBuiltInKeywordsimport com.kms.katalon.core.webui.driver.DriverFactory as DriverFactoryimport com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUiBuiltInKeywordsimport internal.GlobalVariable as GlobalVariableimport com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUIimport com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as Mobileimport com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WSimport com.thoughtworks.selenium.Seleniumimport org.openqa.selenium.firefox.FirefoxDriverimport org.openqa.selenium.WebDriverimport org.openqa.selenium.Keysimport org.openqa.selenium.StaleElementReferenceExceptionimport org.openqa.selenium.WebElementimport org.openqa.selenium.interactions.Actionsimport org.openqa.selenium.support.ui.ExpectedConditionsimport org.openqa.selenium.support.ui.WebDriverWaitimport org.openqa.selenium.support.ui.Selectimport org.openqa.selenium.JavascriptExecutorimport org.junit.Afterimport com.thoughtworks.selenium.webdriven.WebDriverBackedSeleniumimport static org.junit.Assert.*import java.util.regex.Patternimport static org.apache.commons.lang3.StringUtils.joinimport java.text.SimpleDateFormatimport internal.GlobalVariableimport MobileBuiltInKeywords as Mobileimport WSBuiltInKeywords as WSimport WebUiBuiltInKeywords as WebUI import java.util.HashMapimport 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 https: aois) { if (aoi.findElementByXPath("./td[1]/a").getAttribute("title") == region) { js.executeScript("arguments[0].click()", aoigithub.findElementByXPath("./td[2]/a")) WebElement[] tables = driver.findElementsByXPath('//table[@class="resizableContentPanel"]') for (int quartersecond = 0; quartersecond <= 120; quartersecond++){ boolean exit = false for (WebElement table : tables) { if (table.getAttribute('aria-label') == 'Are you sure you want to delete this Saved AOI?') { WebElement okBtn = table.findElementByXPath('./tbody/tr[2]/td/table/tbody/tr[2]/td/table/tbody/tr/td[2]/table/tbody/tr/td/div/div/div/div/div/table/tbody/tr[2]/td[2]/table/tbody/tr/td[2]/div') js.executeScript("arguments[0].click()", okBtn) break; } } return true } } } } catch (Exception e) { return false } }  /** * Logs user out of EODMS */ public void logout(){ selClick("id=gwt-uid-2") selClick("id=gwt-uid-6") for (int second = 0;second <= 60; second++) { try { if (selenium.isVisible("link=Login")) break; } catch (Exception e) {} Thread.sleep(1000); } Thread.sleep(1000); }  //reset selenium public void selen(WebDriverBackedSelenium selenium){ this.selenium = selenium; }  public WebBrowsing(WebDriverBackedSelenium selenium, StartGUI gui){ this.selenium = selenium; this.gui = gui; }}</pre> Script<pre> /** * Main control for EODMS Scene Retriever. * * Takes user input for start of run and controls WebBrowsing functions. * * @author Kieran Moynihan, Khang Nguyen */ import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpointimport static com.kms.katalon.core.testcase.TestCaseFactory.findTestCaseimport static com.kms.katalon.core.testdata.TestDataFactory.findTestDataimport static com.kms.katalon.core.testobject.ObjectRepository.findTestObjectimport com.kms.katalon.core.checkpoint.Checkpoint as Checkpointimport com.kms.katalon.core.checkpoint.CheckpointFactory as CheckpointFactoryimport com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as MobileBuiltInKeywordsimport com.kms.katalon.core.model.FailureHandling as FailureHandlingimport com.kms.katalon.core.testcase.TestCase as TestCaseimport com.kms.katalon.core.testcase.TestCaseFactory as TestCaseFactoryimport com.kms.katalon.core.testdata.TestData as TestDataimport com.kms.katalon.core.testdata.TestDataFactory as TestDataFactoryimport com.kms.katalon.core.testobject.ObjectRepository as ObjectRepositoryimport com.kms.katalon.core.testobject.TestObject as TestObjectimport com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WSBuiltInKeywordsimport com.kms.katalon.core.webui.driver.DriverFactory as DriverFactoryimport com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUiBuiltInKeywordsimport internal.GlobalVariable as GlobalVariableimport com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUIimport com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as Mobileimport com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WSimport org.openqa.selenium.WebDriverimport org.openqa.selenium.WebElementimport org.openqa.selenium.JavascriptExecutorimport com.thoughtworks.selenium.webdriven.WebDriverBackedSeleniumimport static org.junit.Assert.*import java.util.regex.Patternimport static org.apache.commons.lang3.StringUtils.joinimport java.text.SimpleDateFormat // launch startGUI// StartGUI provides two input fields for user to enter a username and password for EODMSStartGUI gui = new StartGUI();// wait for user to finish entering loginwhile(gui.done() == false){ Thread.sleep(250)}gui.dispose() // open browser and go to URLWebUI.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 EODMSselenium.selectFrame("index=0")// wait for login button to load with the pagefor (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 searchint 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 scene-= 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>retriever

Navigation menu

GCwiki