- Timestamp:
- 07/23/15 15:08:29 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/commands/CMDgenerateSeleniumReplay.java
r2023 r2029 13 13 // limitations under the License. 14 14 15 /* Selenium IDE test case template:16 * --------------------------------------------------17 * <?xml version="1.0" encoding="${encoding}"?>18 * <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">19 * <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">20 * <head profile="http://selenium-ide.openqa.org/profiles/test-case">21 * <meta http-equiv="Content-Type" content="text/html; charset=${encoding}" />22 * <link rel="selenium.base" href="${baseURL}" />23 * <title>${name}</title>24 * </head>25 * <body>26 * <table cellpadding="1" cellspacing="1" border="1">27 * <thead>28 * <tr><td rowspan="1" colspan="3">${name}</td></tr>29 * </thead><tbody>30 * ${commands}31 * </tbody></table>32 * </body>33 * </html>34 *35 * ------------------------------------36 * baseURL: home page37 * name: test case name38 * commands: Template:39 * <tr>\n" +40 * \t<td>${command.command}</td>41 * \t<td>${command.target}</td>42 * \t<td>${command.value}</td>43 * </tr>44 *45 */46 15 package de.ugoe.cs.autoquest.plugin.html.commands; 47 16 … … 80 49 */ 81 50 public class CMDgenerateSeleniumReplay implements Command { 82 /* 83 * (non-Javadoc) 84 * 85 * @see de.ugoe.cs.util.console.Command#run(java.util.List) 86 */ 87 @SuppressWarnings("unchecked") 88 @Override 89 public void run(List<Object> parameters) { 90 String sequencesName = "sequences"; 91 String folder = null; 92 String baseURL = null; // default 93 try { 94 if (parameters.size() == 2) { 95 folder = (String) parameters.get(0); 96 baseURL = (String) parameters.get(1); 97 } else if (parameters.size() == 3) { 98 sequencesName = (String) parameters.get(0); 99 folder = (String) parameters.get(1); 100 baseURL = (String) parameters.get(2); 101 } else { 102 throw new IllegalArgumentException( 103 "The command needs two or three parameters."); 104 } 105 106 if (!(new File(folder).isDirectory())) { 107 throw new IllegalArgumentException("HTML files folder path: " 108 + folder + " is invalid."); 109 } 110 // validate the basic URL 111 // HttpURLConnection.setFollowRedirects(false); 112 HttpURLConnection httpURLConnection = (HttpURLConnection) new URL( 113 baseURL).openConnection(); 114 httpURLConnection.setRequestMethod("HEAD"); 115 if (!(httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK)) { 116 throw new IllegalArgumentException("Website basic URL: " 117 + baseURL + " is invalid."); 118 } 119 } catch (SecurityException se) { 120 throw new IllegalArgumentException( 121 "Parameters are invalid"); 122 } catch (MalformedURLException mue) { 123 throw new IllegalArgumentException("Website basic URL: " 124 + baseURL + " is invalid."); 125 } catch (IOException e) { 126 throw new IllegalArgumentException(e); 127 } 128 129 try { 130 List<List<Event>> sequences = null; 131 Object dataObject = GlobalDataContainer.getInstance().getData( 132 sequencesName); 133 if (dataObject == null) { 134 CommandHelpers.objectNotFoundMessage(sequencesName); 135 return; 136 } 137 if (!SequenceInstanceOf.isCollectionOfSequences(dataObject)) { 138 CommandHelpers.objectNotType(sequencesName, 139 "Collection<List<Event<?>>>"); 140 return; 141 } 142 sequences = (List<List<Event>>) dataObject; 143 144 String command = null; 145 String target = null; 146 String value = null; 147 for (int seqsIndex = 0; seqsIndex < sequences.size(); seqsIndex++) { 148 LinkedList<Map<String, String>> attributeList = new LinkedList<Map<String, String>>(); 149 List<Event> sequence = sequences.get(seqsIndex); 150 Event firstEvent = sequence.get(0); 151 HTMLGUIElement htmlGUIElement = (HTMLGUIElement) firstEvent.getTarget(); 152 while (!(htmlGUIElement instanceof HTMLDocument)) { // the first target must be a page 153 htmlGUIElement = (HTMLGUIElement) (htmlGUIElement.getParent()); 154 } 155 command = "open"; 156 target = ((HTMLDocument) htmlGUIElement).getPath(); 157 value = ""; 158 addToAttrList(attributeList, command, target, value); 159 160 for (int seqIndex = 1; seqIndex < sequence.size(); seqIndex++) { 161 Event event = sequence.get(seqIndex); 162 target = getXpath(event.getTarget()); 163 // Login button is global, must await the last page to load 164 // otherwise, will lead to wrong page after logging in 165 if (target.equals("//ul[@id='navlist2']/li[2]/a") 166 && (attributeList.size() > 1) 167 && !attributeList.getLast().get("command") 168 .endsWith("AndWait")) { 169 attributeList.getLast().put( 170 "command", 171 attributeList.getLast().get("command") 172 + "AndWait"); 173 } 174 175 if (event.getType() instanceof MouseClick 176 && (((MouseClick) event.getType()).getButton() == Button.LEFT || ((MouseClick) event 177 .getType()).getButton() == Button.MIDDLE)) { 178 command = "click"; 179 String precedingCommand = "waitForElementPresent"; 180 value = ""; 181 addToAttrList(attributeList, precedingCommand, target, 182 value); 183 } else if (event.getType() instanceof TextInput) { 184 command = "type"; 185 value = ((TextInput) event.getType()).getEnteredText(); 186 // if the session contains login process, 187 // the session must log out at beginning 188 if (target 189 .equals("//form[@id='user-login']/div/div/input[@id='edit-name']") 190 && !attributeList.get(0).get("target") 191 .equals("/user/logout")) { 192 addToAttrList(attributeList, "open", 193 "/user/logout", "", 0); 194 } 195 } else if (event.getType() instanceof KeyPressed) { 196 command = "sendKeys"; 197 VirtualKey pressedKey = ((KeyPressed) event.getType()) 198 .getKey(); 199 switch (pressedKey) { 200 case ENTER: 201 value = "${KEY_ENTER}"; 202 break; 203 case TAB: 204 value = "${KEY_TAB}"; 205 } 206 } else {// Scroll or KeyboardFocusChange or else 207 continue; 208 } 209 addToAttrList(attributeList, command, target, value); 210 } 211 212 if (attributeList.size() > 0) { 213 createHTML(folder, "session-" + seqsIndex + ".html", 214 baseURL, attributeList, "UTF-8"); 215 } else { // the sequence has no action 216 continue; 217 } 218 } 219 } catch (Exception e) { 220 Console.printerrln("Error on running the command."); 221 e.printStackTrace(); 222 } 223 } 224 225 /** 226 * create event files in HTML with Selenium IDE template 227 * 228 * @param HTMLFolder 229 * @param fileName 230 * @param attributeList 231 */ 232 private void createHTML(String HTMLFolder, String fileName, String baseURL, 233 List<Map<String, String>> attributeList, String encoding) { 234 235 String htmlStr = "<?xml version=\"1.0\" encoding=\"${encoding}\"?>\n" 236 + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" " 237 + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" 238 + "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" 239 + "<head profile=\"http://selenium-ide.openqa.org/profiles/test-case\">\n" 240 + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=${encoding}\" />\n" 241 + "<link rel=\"selenium.base\" href=\"${baseURL}\" />\n" 242 + "<title>${name}</title>\n" 243 + "</head>\n" 244 + "<body>\n" 245 + "<table cellpadding=\"1\" cellspacing=\"1\" border=\"1\">\n" 246 + "<thead>\n" 247 + "<tr><td rowspan=\"1\" colspan=\"3\">${name}</td></tr>\n" 248 + "</thead><tbody>\n"; 249 htmlStr = htmlStr.replace("${encoding}", encoding); 250 htmlStr = htmlStr.replace("${baseURL}", baseURL); 251 htmlStr = htmlStr.replace("${name}", fileName.replace(".html", "")); 252 for (Map<String, String> commandMap : attributeList) { 253 htmlStr = htmlStr + "<tr>\n" 254 + "\t<td>" + commandMap.get("command") + "</td>\n" 255 + "\t<td>" + commandMap.get("target") + "</td>\n" 256 + "\t<td>" + commandMap.get("value") + "</td>\n" 257 + "</tr>\n"; 258 } 259 260 String fileEnding = "</tbody></table>\n</body>\n</html>"; 261 htmlStr = htmlStr + fileEnding; 262 try { 263 File newHtmlFile = new File(HTMLFolder 264 + System.getProperty("file.separator") + fileName); 265 BufferedWriter bw = new BufferedWriter(new FileWriter(newHtmlFile)); 266 bw.write(htmlStr); 267 bw.flush(); 268 bw.close(); 269 } catch (Exception e) { 270 Console.printerrln("Error on creating xhtml files."); 271 e.printStackTrace(); 272 } 273 } 274 275 /** 276 * add an event to the event list 277 * 278 * @param attributeList 279 * @param command 280 * @param target 281 * @param value 282 * 283 */ 284 private void addToAttrList(LinkedList<Map<String, String>> attributeList, 285 String command, String target, String value) { 286 Map<String, String> ctvMap = new HashMap<String, String>(); 287 ctvMap.put("command", command); 288 ctvMap.put("target", target); 289 ctvMap.put("value", value); 290 attributeList.add(ctvMap); 291 } 292 293 private void addToAttrList(LinkedList<Map<String, String>> attributeList, 294 String command, String target, String value, int position) { 295 Map<String, String> ctvMap = new HashMap<String, String>(); 296 ctvMap.put("command", command); 297 ctvMap.put("target", target); 298 ctvMap.put("value", value); 299 attributeList.add(position, ctvMap); 300 } 301 302 /** 303 * 304 * @param iEventTarget 305 * @return the relative xpath 306 */ 307 private String getXpath(IEventTarget iEventTarget) { 308 HTMLGUIElement htmlGUIElement = (HTMLGUIElement) iEventTarget; 309 List<String> xpathElements = new LinkedList<String>(); 310 String htmlId = null; 311 int htmlIndex = 0; 312 313 // obtain the relative xpath of the element 314 while (!(htmlGUIElement instanceof HTMLDocument)) { 315 HTMLPageElement htmlPageElement = (HTMLPageElement) htmlGUIElement; 316 StringBuffer xpathElement = new StringBuffer(); 317 // the real tag is "input" without _* 318 xpathElement.append(htmlPageElement.getTagName() 319 .replace("input_text", "input") 320 .replace("input_password", "input") 321 .replace("input_submit", "input")); 322 // better not use absolute xpath, 323 // Selenium IDE specifies only the 324 // 1st tag's id, if it's not the only tag 325 if ( (htmlId = htmlPageElement.getHtmlId()) != null) { 326 xpathElement.append("[@id='"); 327 xpathElement.append(htmlId); 328 xpathElement.append("']"); 329 xpathElements.add(0, xpathElement.toString()); 330 // the xpath must have more then one tag with id 331 // but the Selenium IDE uses only the 1st one 332 // which is enough for finding out the element 333 if (xpathElements.size() > 1) { 334 break; 335 } 336 } else if ((htmlIndex = htmlPageElement.getIndex()) != 0) { 337 xpathElement.append("["); 338 // find element by xpath, index starts from 1, not 0 339 xpathElement.append(htmlIndex + 1); 340 xpathElement.append("]"); 341 xpathElements.add(0, xpathElement.toString()); 342 } else { 343 // if the index is 0, add only tag 344 xpathElements.add(0, xpathElement.toString()); 345 } 346 htmlGUIElement = (HTMLGUIElement) (htmlGUIElement.getParent()); 347 } 348 349 StringBuffer xPathStatement = new StringBuffer(); 350 xPathStatement.append("/"); 351 for (String xpathElem : xpathElements) { 352 xPathStatement.append("/"); 353 xPathStatement.append(xpathElem); 354 } 355 356 return xPathStatement.toString(); 357 } 358 359 /* 360 * (non-Javadoc) 361 * 362 * @see de.ugoe.cs.util.console.Command#help() 363 */ 364 @Override 365 public String help() { 366 367 return "generateSeleniumReplay [sequenceName] <HTMLFilesFolder> <websiteBaseURL> \n " 368 + "The default sequenceName is 'sequences' got from default sequence name of command 'parseDirHTML'"; 369 } 51 /* 52 * (non-Javadoc) 53 * 54 * @see de.ugoe.cs.util.console.Command#run(java.util.List) 55 */ 56 @SuppressWarnings("unchecked") 57 @Override 58 public void run(List<Object> parameters) { 59 String sequencesName = "sequences"; 60 String folder = null; 61 String baseURL = null; // default 62 try { 63 if (parameters.size() == 2) { 64 folder = (String) parameters.get(0); 65 baseURL = (String) parameters.get(1); 66 } 67 else if (parameters.size() == 3) { 68 sequencesName = (String) parameters.get(0); 69 folder = (String) parameters.get(1); 70 baseURL = (String) parameters.get(2); 71 } 72 else { 73 throw new IllegalArgumentException("The command needs two or three parameters."); 74 } 75 76 if (!(new File(folder).isDirectory())) { 77 throw new IllegalArgumentException("HTML files folder path: " + folder + 78 " is invalid."); 79 } 80 // validate the basic URL 81 // HttpURLConnection.setFollowRedirects(false); 82 HttpURLConnection httpURLConnection = 83 (HttpURLConnection) new URL(baseURL).openConnection(); 84 httpURLConnection.setRequestMethod("HEAD"); 85 if (!(httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK)) { 86 throw new IllegalArgumentException("Website basic URL: " + baseURL + " is invalid."); 87 } 88 } 89 catch (SecurityException se) { 90 throw new IllegalArgumentException("Parameters are invalid"); 91 } 92 catch (MalformedURLException mue) { 93 throw new IllegalArgumentException("Website basic URL: " + baseURL + " is invalid."); 94 } 95 catch (IOException e) { 96 throw new IllegalArgumentException(e); 97 } 98 99 try { 100 List<List<Event>> sequences = null; 101 Object dataObject = GlobalDataContainer.getInstance().getData(sequencesName); 102 if (dataObject == null) { 103 CommandHelpers.objectNotFoundMessage(sequencesName); 104 return; 105 } 106 if (!SequenceInstanceOf.isCollectionOfSequences(dataObject)) { 107 CommandHelpers.objectNotType(sequencesName, "Collection<List<Event<?>>>"); 108 return; 109 } 110 sequences = (List<List<Event>>) dataObject; 111 112 String command = null; 113 String target = null; 114 String value = null; 115 for (int seqsIndex = 0; seqsIndex < sequences.size(); seqsIndex++) { 116 LinkedList<Map<String, String>> attributeList = 117 new LinkedList<Map<String, String>>(); 118 List<Event> sequence = sequences.get(seqsIndex); 119 Event firstEvent = sequence.get(0); 120 HTMLGUIElement htmlGUIElement = (HTMLGUIElement) firstEvent.getTarget(); 121 while (!(htmlGUIElement instanceof HTMLDocument)) { // the first target must be a 122 // page 123 htmlGUIElement = (HTMLGUIElement) (htmlGUIElement.getParent()); 124 } 125 command = "open"; 126 target = ((HTMLDocument) htmlGUIElement).getPath(); 127 value = ""; 128 addToAttrList(attributeList, command, target, value); 129 130 for (int seqIndex = 1; seqIndex < sequence.size(); seqIndex++) { 131 Event event = sequence.get(seqIndex); 132 target = getXpath(event.getTarget()); 133 // Login button is global, must await the last page to load 134 // otherwise, will lead to wrong page after logging in 135 if (target.equals("//ul[@id='navlist2']/li[2]/a") && 136 (attributeList.size() > 1) && 137 !attributeList.getLast().get("command").endsWith("AndWait")) 138 { 139 attributeList.getLast().put("command", 140 attributeList.getLast().get("command") + 141 "AndWait"); 142 } 143 144 if (event.getType() instanceof MouseClick && 145 (((MouseClick) event.getType()).getButton() == Button.LEFT || ((MouseClick) event 146 .getType()).getButton() == Button.MIDDLE)) 147 { 148 command = "click"; 149 String precedingCommand = "waitForElementPresent"; 150 value = ""; 151 addToAttrList(attributeList, precedingCommand, target, value); 152 } 153 else if (event.getType() instanceof TextInput) { 154 command = "type"; 155 value = ((TextInput) event.getType()).getEnteredText(); 156 // if the session contains login process, 157 // the session must log out at beginning 158 if (target 159 .equals("//form[@id='user-login']/div/div/input[@id='edit-name']") && 160 !attributeList.get(0).get("target").equals("/user/logout")) 161 { 162 addToAttrList(attributeList, "open", "/user/logout", "", 0); 163 } 164 } 165 else if (event.getType() instanceof KeyPressed) { 166 command = "sendKeys"; 167 VirtualKey pressedKey = ((KeyPressed) event.getType()).getKey(); 168 switch (pressedKey) 169 { 170 case ENTER: 171 value = "${KEY_ENTER}"; 172 break; 173 case TAB: 174 value = "${KEY_TAB}"; 175 } 176 } 177 else {// Scroll or KeyboardFocusChange or else 178 continue; 179 } 180 addToAttrList(attributeList, command, target, value); 181 } 182 183 if (attributeList.size() > 0) { 184 createHTML(folder, "session-" + seqsIndex + ".html", baseURL, attributeList, 185 "UTF-8"); 186 } 187 else { // the sequence has no action 188 continue; 189 } 190 } 191 } 192 catch (Exception e) { 193 Console.printerrln("Error on running the command."); 194 e.printStackTrace(); 195 } 196 } 197 198 /** 199 * create event files in HTML with Selenium IDE template 200 * 201 * @param HTMLFolder 202 * @param fileName 203 * @param attributeList 204 */ 205 private void createHTML(String HTMLFolder, 206 String fileName, 207 String baseURL, 208 List<Map<String, String>> attributeList, 209 String encoding) 210 { 211 212 String htmlStr = 213 "<?xml version=\"1.0\" encoding=\"${encoding}\"?>\n" 214 + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" " 215 + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" 216 + "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" 217 + "<head profile=\"http://selenium-ide.openqa.org/profiles/test-case\">\n" 218 + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=${encoding}\" />\n" 219 + "<link rel=\"selenium.base\" href=\"${baseURL}\" />\n" 220 + "<title>${name}</title>\n" + "</head>\n" + "<body>\n" 221 + "<table cellpadding=\"1\" cellspacing=\"1\" border=\"1\">\n" + "<thead>\n" 222 + "<tr><td rowspan=\"1\" colspan=\"3\">${name}</td></tr>\n" + "</thead><tbody>\n"; 223 htmlStr = htmlStr.replace("${encoding}", encoding); 224 htmlStr = htmlStr.replace("${baseURL}", baseURL); 225 htmlStr = htmlStr.replace("${name}", fileName.replace(".html", "")); 226 for (Map<String, String> commandMap : attributeList) { 227 htmlStr = 228 htmlStr + "<tr>\n" + "\t<td>" + commandMap.get("command") + "</td>\n" + "\t<td>" + 229 commandMap.get("target") + "</td>\n" + "\t<td>" + commandMap.get("value") + 230 "</td>\n" + "</tr>\n"; 231 } 232 233 String fileEnding = "</tbody></table>\n</body>\n</html>"; 234 htmlStr = htmlStr + fileEnding; 235 try { 236 File newHtmlFile = 237 new File(HTMLFolder + System.getProperty("file.separator") + fileName); 238 BufferedWriter bw = new BufferedWriter(new FileWriter(newHtmlFile)); 239 bw.write(htmlStr); 240 bw.flush(); 241 bw.close(); 242 } 243 catch (Exception e) { 244 Console.printerrln("Error on creating xhtml files."); 245 e.printStackTrace(); 246 } 247 } 248 249 /** 250 * add an event to the event list 251 * 252 * @param attributeList 253 * @param command 254 * @param target 255 * @param value 256 * 257 */ 258 private void addToAttrList(LinkedList<Map<String, String>> attributeList, 259 String command, 260 String target, 261 String value) 262 { 263 Map<String, String> ctvMap = new HashMap<String, String>(); 264 ctvMap.put("command", command); 265 ctvMap.put("target", target); 266 ctvMap.put("value", value); 267 attributeList.add(ctvMap); 268 } 269 270 private void addToAttrList(LinkedList<Map<String, String>> attributeList, 271 String command, 272 String target, 273 String value, 274 int position) 275 { 276 Map<String, String> ctvMap = new HashMap<String, String>(); 277 ctvMap.put("command", command); 278 ctvMap.put("target", target); 279 ctvMap.put("value", value); 280 attributeList.add(position, ctvMap); 281 } 282 283 /** 284 * 285 * @param iEventTarget 286 * @return the relative xpath 287 */ 288 private String getXpath(IEventTarget iEventTarget) { 289 HTMLGUIElement htmlGUIElement = (HTMLGUIElement) iEventTarget; 290 List<String> xpathElements = new LinkedList<String>(); 291 String htmlId = null; 292 int htmlIndex = 0; 293 294 // obtain the relative xpath of the element 295 while (!(htmlGUIElement instanceof HTMLDocument)) { 296 HTMLPageElement htmlPageElement = (HTMLPageElement) htmlGUIElement; 297 StringBuffer xpathElement = new StringBuffer(); 298 // the real tag is "input" without _* 299 xpathElement.append(htmlPageElement.getTagName().replace("input_text", "input") 300 .replace("input_password", "input").replace("input_submit", "input")); 301 // better not use absolute xpath, 302 // Selenium IDE specifies only the 303 // 1st tag's id, if it's not the only tag 304 if ((htmlId = htmlPageElement.getHtmlId()) != null) { 305 xpathElement.append("[@id='"); 306 xpathElement.append(htmlId); 307 xpathElement.append("']"); 308 xpathElements.add(0, xpathElement.toString()); 309 // the xpath must have more then one tag with id 310 // but the Selenium IDE uses only the 1st one 311 // which is enough for finding out the element 312 if (xpathElements.size() > 1) { 313 break; 314 } 315 } 316 else if ((htmlIndex = htmlPageElement.getIndex()) != 0) { 317 xpathElement.append("["); 318 // find element by xpath, index starts from 1, not 0 319 xpathElement.append(htmlIndex + 1); 320 xpathElement.append("]"); 321 xpathElements.add(0, xpathElement.toString()); 322 } 323 else { 324 // if the index is 0, only add tag 325 xpathElements.add(0, xpathElement.toString()); 326 } 327 htmlGUIElement = (HTMLGUIElement) (htmlGUIElement.getParent()); 328 } 329 330 StringBuffer xPathStatement = new StringBuffer(); 331 xPathStatement.append("/"); 332 for (String xpathElem : xpathElements) { 333 xPathStatement.append("/"); 334 xPathStatement.append(xpathElem); 335 } 336 337 return xPathStatement.toString(); 338 } 339 340 /* 341 * (non-Javadoc) 342 * 343 * @see de.ugoe.cs.util.console.Command#help() 344 */ 345 @Override 346 public String help() { 347 348 return "generateSeleniumReplay [sequenceName] <HTMLFilesFolder> <websiteBaseURL>"; 349 } 370 350 371 351 }
Note: See TracChangeset
for help on using the changeset viewer.