| Line 1: | Line 1: | 
| − | = Login = 
 | + | 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.mobile.keyword.MobileBuiltInKeywords as Mobile
 |  | 
|  | 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.webservice.keyword.WSBuiltInKeywords asWS | + | 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 GlobalVariable | + | 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']") | 
|  | + | 	} | 
|  |  |  |  | 
| − | WebUI.openBrowser('https://www.eodms-sgdot.nrcan-rncan.gc.ca//index_en.jsp')
 | + | 	/** | 
|  | + | 	 * 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 | 
|  | + | 	} | 
|  |  |  |  | 
| − | WebUI.switchToFrame(findTestObject('Frame'),30)
 | + | 	/** | 
|  | + | 	 * Default value override of order() | 
|  | + | 	 * - Default max scenes per cart is 50 | 
|  | + | 	 */ | 
|  | + | 	public String[] order (String sDate, String eDate) { | 
|  | + | 		order(sDate, eDate, 50) | 
|  | + | 	} | 
|  |  |  |  | 
| − | WebUI.waitForElementVisible(findTestObject('Login'), 20)
 | + | 	/** | 
|  | + | 	 * 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; | 
|  |  |  |  | 
| − | WebUI.click(findTestObject('Login'))
 | + | 		// 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; | 
|  | + | 	} | 
|  |  |  |  | 
| − | WebUI.sendKeys(findTestObject('username'), 'XXX')
 | + | 	/** | 
|  | + | 	 * 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 | 
|  | + | 		} | 
|  | + | 	} | 
|  |  |  |  | 
| − | WebUI.sendKeys(findTestObject('password'), 'XXX')
 | + | 	/** | 
|  | + | 	 * 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); | 
|  | + | 	} | 
|  |  |  |  | 
| − | WebUI.click(findTestObject('login_button'))
 | + | 	//reset selenium | 
|  | + | 	public void selen(WebDriverBackedSelenium selenium){ | 
|  | + | 		this.selenium = selenium; | 
|  | + | 	} | 
|  |  |  |  | 
| − | WebUI.waitForElementClickable(findTestObject('name_upon_login'),20)
 | + | 	public WebBrowsing(WebDriverBackedSelenium selenium, StartGUI gui){ | 
|  | + | 		this.selenium = selenium; | 
|  | + | 		this.gui = gui; | 
|  | + | 	} | 
|  | + | } | 
|  | </pre> |  | </pre> | 
|  |  |  |  | 
| − | = Sample Search = 
 | + | Script | 
|  | + | <pre> | 
|  | + |   | 
|  | + | /** | 
|  | + |  * Main control for EODMS Scene Retriever. | 
|  | + |  *  | 
|  | + |  * Takes user input for start of run and controls WebBrowsing functions. | 
|  | + |  *  | 
|  | + |  * @author Kieran Moynihan, Khang Nguyen | 
|  | + |  */ | 
|  |  |  |  | 
| − | <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 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.mobile.keyword.MobileBuiltInKeywords as Mobile
 |  | 
|  | 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.webservice.keyword.WSBuiltInKeywords asWS | + | 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 asGlobalVariable | + | 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 | 
|  |  |  |  | 
| − | WebUI.click(findTestObject('search_for_data'))
 | + | // 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.click(findTestObject('search_tabs/selectdates')) | + | // 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); | 
|  | + | } | 
|  |  |  |  | 
| − | WebUI.click(findTestObject('date_all_time'))
 | + | //num will be the number of scans returned by the search | 
|  | + | int num; | 
|  |  |  |  | 
| − | WebUI.click(findTestObject('search_tabs/data_selection'))
 | + | SearchParameters SearchDetails; | 
|  |  |  |  | 
| − | WebUI.click(findTestObject('Data/RS2'))
 | + | try{ | 
| − |   | + | 	//log the user into EODMS using the provided login information | 
| − | WebUI.click(findTestObject('search_tabs/submit_search_tab'))
 | + | 	web.login(); | 
| − |   | + | 	 | 
| − | WebUI.delay(3)
 | + | 	//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 | 
| − | WebUI.waitForElementClickable(findTestObject('submit_search/number_of_results'),20)
 | + | 	//This tool will read the webelements after user presses start in order to determine which options were selected | 
| − |   | + | 	WaitGUI gui2 = new WaitGUI(); | 
| − | WebUI.click(findTestObject('submit_search/number_of_results'))
 | + | 	while (gui2.done() == false){ | 
| − |   | + | 		Thread.sleep(250) | 
| − | WebUI.click(findTestObject('submit_search/10_results'))
 | + | 	} | 
| − |   | + | 	gui2.dispose() | 
| − | WebUI.click(findTestObject('submit_search/search'))
 | + | 	 | 
|  | + | 	//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> | 
| − | 
 |  | 
| − | = Sample Search =
 |  |