protected boolean exist() throws SAFSException { String debugmsg = StringUtils.debugmsg(false); try { boolean isShowing = false; // wait for the window - secTimout of 0 means a single try to search for given comps // waitForObject checks only component validity and tells nothing about its visibility int status = sUtils.waitForObject(mapname, windowName, compName, 0); if (status == 0) { // component search succeeded isShowing = compIsVisible("//HTML[1]"); SGuiObject obj; obj = sHelper.getCompTestObject(); if (isShowing && (obj != null)) { isShowing = compIsVisible(obj.getLocator()); } } // else status!=0, which means that component search failed return isShowing; } catch (SAFSObjectNotFoundException sonfe) { Log.warn(debugmsg + " Met Exception " + StringUtils.debugmsg(sonfe)); } return false; }
/** * Convert 'json object' to a certain type. * * @param clazz Class<T>, the expected type to which the json object will be converted. * @param jsonData Object, the json data object. * @return T, the converted 'json object'; null if something wrong happened. */ public static <T> T convert(Class<T> clazz, Object jsonData) { try { if (clazz == null || jsonData == null) { IndependantLog.error(StringUtils.debugmsg(false) + " converted-clazz or jsonData is null."); return null; } JsonToBeanConverter converter = new JsonToBeanConverter(); return converter.convert(clazz, jsonData); } catch (JsonException e) { IndependantLog.error( StringUtils.debugmsg(false) + "Fail to get convert JSON data to " + clazz.getSimpleName(), e); throw null; } }
/* (non-Javadoc) * CANAGL -- this seems to be called prior to EVERY single Step in the script. * So only initialize IF we don't already have one. * @see com.sebuilder.interpreter.TestRun#initRemoteWebDriver() */ @Override public void initRemoteWebDriver() { getLog().info("WDTestRun.initRemoteWebDriver invoked."); if (getDriver() != null) { getLog().info("WDTestRun.initRemoteWebDriver detected session already exists..."); return; } int timeout = 30; // TODO get from parameters in this object! String browserID = "sebuilder_run" + System.currentTimeMillis(); try { WDLibrary.startBrowser(null, null, browserID, timeout, true); } catch (Throwable th) { try { WebDriverGUIUtilities.launchSeleniumServers(); try { WDLibrary.startBrowser(null, null, browserID, timeout, true); getLog().info("WDTestRun.initRemoteWebDriver successful starting browser session."); } catch (Throwable th2) { getLog() .debug("WDTestRun.initRemoteWebDriver failed to start a new WebDriver session:", th2); } } catch (SeleniumPlusException e) { getLog() .info( "WDTestRun.initRemoteWebDriver detected the expected RemoteServer is not running and cannot be started: " + StringUtils.debugmsg(e)); } } }
protected boolean performHoverMouse(Point point, int milliseconds) throws SAFSException { String debugmsg = StringUtils.debugmsg(false); try { // TODO handle the point String locator = component().getLocator(); IndependantLog.debug(debugmsg + " hover on element '" + locator + "'"); selenium.mouseOver(locator); StringUtilities.sleep(milliseconds); selenium.mouseOut(locator); } catch (Exception e) { IndependantLog.error(debugmsg + " fail to hover, due to " + StringUtils.debugmsg(e)); return false; } return true; }
private SGuiObject component() { String debugmsg = StringUtils.debugmsg(false); if (compObject == null) { IndependantLog.warn( debugmsg + " the 'componet object' is null, use the 'window object' instead."); // winObject will never be null, as in process() it has been checked. return winObject; } return compObject; }
/** * Read String as input to find encoding. If no encoding is detected, the default system encoding * will be returned. {@link http://code.google.com/p/juniversalchardet/} {@link * http://www-archive.mozilla.org/projects/intl/UniversalCharsetDetection.html} * * @param String * @return String, the file encoding, it might be null. * @see FileUtilities#detectFileEncoding(String) */ public static String detectStringEncoding(String str) { String encoding = null; try { UniversalDetector detector = new UniversalDetector(null); detector.handleData(str.getBytes(), 0, str.getBytes().length); detector.dataEnd(); // Get the file encoding string (defined in org.mozilla.universalchardet.Constants) encoding = detector.getDetectedCharset(); detector.reset(); } catch (Exception e) { IndependantLog.warn(StringUtils.debugmsg(false) + StringUtils.debugmsg(e)); } // If no encoding is detected, get the default file encoding try { if (encoding == null || encoding.trim().isEmpty()) encoding = System.getProperty("file.encoding"); if (!Charset.isSupported(encoding)) { String error = "The detected encoding is '" + encoding + "', it is not supported by java.nio.charset.Charset"; IndependantLog.warn( error); // We need to map org.mozilla.universalchardet.Constants and // java.nio.charset.Charset ? throw new IOException(error); } } catch (Exception e) { IndependantLog.warn(StringUtils.debugmsg(false) + StringUtils.debugmsg(e)); } return encoding; }
/** * Opens a FileInputStream and detects its encoding. If no encoding is detected, the default * system encoding will be returned. {@link http://code.google.com/p/juniversalchardet/} {@link * http://www-archive.mozilla.org/projects/intl/UniversalCharsetDetection.html} * * @param filename case-insensitive absolute filename path. * @return String, the file encoding, it might be null. * @see FileUtilities#detectFileEncoding(String) */ public static String detectFileEncoding(String filename) { byte[] buf = new byte[4096]; int nread = 0; int totalReadBytes = 0; String encoding = null; FileInputStream fis = null; try { fis = new FileInputStream(new CaseInsensitiveFile(filename).toFile()); UniversalDetector detector = new UniversalDetector(null); // Feed detector with bytes until it detect the encoding or reach the max bytes to read // if the detector can't get the encoding after reading some bytes, we should stop to save // time. while ((nread = fis.read(buf)) > 0 && !detector.isDone() && totalReadBytes < MAX_BTYES_TO_READ) { totalReadBytes += nread; detector.handleData(buf, 0, nread); } if (!detector.isDone()) { // IndependantLog.warn("Didn't detect file encoding after reading "+totalReadBytes+" // bytes."); } detector.dataEnd(); // Get the file encoding string (defined in org.mozilla.universalchardet.Constants) encoding = detector.getDetectedCharset(); detector.reset(); } catch (Exception e) { IndependantLog.warn(StringUtils.debugmsg(false) + StringUtils.debugmsg(e)); } finally { if (fis != null) try { fis.close(); } catch (Exception e) { } } // If no encoding is detected, test if it is "utf-8" try { if (encoding == null || encoding.trim().isEmpty()) if (FileUtilities.isFileUTF8(filename)) encoding = "UTF-8"; } catch (Exception e) { IndependantLog.warn(StringUtils.debugmsg(false) + StringUtils.debugmsg(e)); } // If no encoding is detected, get the default file encoding try { if (encoding == null || encoding.trim().isEmpty()) encoding = System.getProperty("file.encoding"); if (!Charset.isSupported(encoding)) { String error = "The detected encoding is '" + encoding + "', it is not supported by java.nio.charset.Charset"; IndependantLog.warn( error); // We need to map org.mozilla.universalchardet.Constants and // java.nio.charset.Charset ? throw new IOException(error); } } catch (Exception e) { IndependantLog.warn(StringUtils.debugmsg(false) + StringUtils.debugmsg(e)); } return encoding; }
/** * <b>Purpose:</b> Verify the complete status of the current popup menu with a benchmark file. * * @throws SAFSException */ protected void verifyPopupMenu() throws SAFSException { String debugmsg = getClass().getName() + ".verifyPopupMenu() "; String benchFileName = null, headerString = null, testFileName = null, diffFileName = null; // Analyse the four parameters, three of them are optional // benchFileName (required),headerString (optional),testFileName (optional),diffFileName // (optional) if (params.size() < 1) { this.issueParameterCountFailure( FAILStrings.convert( FAILStrings.BAD_PARAM, "Invalid parameter value for BenchmarkFile", "BenchmarkFile")); Log.debug(debugmsg + " Missing parameter of 'benchFileName'!!!"); return; } Iterator iter = params.iterator(); String defaultFileName = iter.next().toString(); Log.info(debugmsg + " default file name (for bench,test,diff): " + defaultFileName); benchFileName = getAbsoluteFileName(defaultFileName, STAFHelper.SAFS_VAR_BENCHDIRECTORY); if (iter.hasNext()) headerString = iter.next().toString(); if (iter.hasNext()) { testFileName = iter.next().toString(); if (testFileName != null && !testFileName.trim().equals("")) { testFileName = getAbsoluteFileName(testFileName, STAFHelper.SAFS_VAR_TESTDIRECTORY); } else { testFileName = getAbsoluteFileName(defaultFileName, STAFHelper.SAFS_VAR_TESTDIRECTORY); } } else { testFileName = getAbsoluteFileName(defaultFileName, STAFHelper.SAFS_VAR_TESTDIRECTORY); } if (iter.hasNext()) { diffFileName = iter.next().toString(); if (diffFileName != null && !diffFileName.trim().equals("")) { diffFileName = getAbsoluteFileName(diffFileName, STAFHelper.SAFS_VAR_DIFDIRECTORY); } else { diffFileName = getAbsoluteFileName(defaultFileName, STAFHelper.SAFS_VAR_DIFDIRECTORY); } } else { diffFileName = getAbsoluteFileName(defaultFileName, STAFHelper.SAFS_VAR_DIFDIRECTORY); } // 1.Get the whole sub-tree of the JMenu provided (the third parameter) GuiSubitemTestObject guiObj = new GuiSubitemTestObject(obj1.getObjectReference()); MenuTree tree = (MenuTree) extractMenuItems(guiObj, 0); // Get a list which contains all nodes' "path=status" List treePathAndStatus = tree.getTreePaths("", true); // 2.Stroe the header-file into the test-file // Store the each node's path and it's status of the sub-tree into the "test-file" if (headerString != null && !headerString.trim().equals("")) { Log.debug(debugmsg + testFileName + " will contains headerString: " + headerString); treePathAndStatus.add(0, headerString); } if (testFileName != null && !testFileName.trim().equals("")) { Log.debug(debugmsg + "Menu status will be saved to " + testFileName); try { StringUtils.writefile(testFileName, treePathAndStatus); } catch (IOException e) { String detail = failedText.convert( FAILStrings.FILE_ERROR, "Can not write to " + testFileName, testFileName); Log.debug(debugmsg + detail); throw new SAFSException(detail); } } // 3.Compare with the bench-file; // If mached, set the testRecord's status to OK. // Otherwise, set the testRecord's status to FAILURE and store the difference to diff-file. List benchContents = new ArrayList(); try { benchContents.addAll(StringUtils.readfile(benchFileName)); } catch (IOException e) { String detail = failedText.convert( FAILStrings.FILE_ERROR, "Can not read " + benchFileName, benchFileName); Log.debug(debugmsg + detail); throw new SAFSException(detail); } Log.debug(debugmsg + "BenchFile Menu's status:" + benchContents); Log.debug(debugmsg + "Current Menu's status:" + treePathAndStatus); // The list differences will contains the difference between current status and bench status List differences = new ArrayList(); if (headerString != null && !headerString.trim().equals("")) { Log.debug(debugmsg + "Compare the header line."); String benchHeader = benchContents.isEmpty() ? "" : benchContents.remove(0).toString(); String currentHeader = treePathAndStatus.remove(0).toString(); Log.debug("benchHeader: " + benchHeader); Log.debug("currentHeader: " + currentHeader); if (!currentHeader.equalsIgnoreCase(benchHeader)) { differences.add( "Header different: \n" + "benchHeader: " + benchHeader + "\n" + "currentHeader: " + currentHeader + "\n\n"); } } // Convert List to Map which contains path as key and status as value Map benchStatusMap = convertToMap(benchContents); Map currentStatusMap = convertToMap(treePathAndStatus); // I. If the two maps have the same path and the same status // II. Else If the two maps have the same path but status are different, then write this // difference to the list differences. // Finally remove the path from both maps Object[] currentPathArray = currentStatusMap.keySet().toArray(); for (int i = 0; i < currentPathArray.length; i++) { String key = currentPathArray[i].toString(); String benchStatus = null; if (benchStatusMap.containsKey(key)) { benchStatus = benchStatusMap.get(key).toString(); } else { continue; } String currentStatus = currentStatusMap.get(key).toString(); Log.debug("menu path: " + key); Log.debug("benchStatusValue: " + benchStatus); Log.debug("currentStatusValue: " + currentStatus); if (!benchStatus.equalsIgnoreCase(currentStatus)) { differences.add( "Menu path: " + key + " has difference: \n" + "benchStatus: " + benchStatus + "\n" + "currentStatus: " + currentStatus + "\n"); } // Finally remove this path from both benchStatusMap and currentStatusMap benchStatusMap.remove(key); currentStatusMap.remove(key); } // III. Else if MenuItem exist only in bench file, write this difference to list differences. if (benchStatusMap.size() != 0) { differences.add("MenuItem exist only in " + benchFileName); Object[] keys = benchStatusMap.keySet().toArray(); for (int i = 0; i < keys.length; i++) { String key = keys[i].toString(); differences.add("Menu path: " + key + " ## Status: " + benchStatusMap.get(key)); } } // IV. Else if MenuItem exist only in current menu, write this difference to list differences. if (currentStatusMap.size() != 0) { differences.add("MenuItem exist only in current menu"); Object[] keys = currentStatusMap.keySet().toArray(); for (int i = 0; i < keys.length; i++) { String key = keys[i].toString(); differences.add("Menu path: " + key + " ## Status: " + currentStatusMap.get(key)); } } // If the size of differences is bigger than 0, there are some differences between current // status and bench status if (differences.size() > 0) { testRecordData.setStatusCode(StatusCodes.GENERAL_SCRIPT_FAILURE); String detail = failedText.convert( GENStrings.CONTENT_NOT_MATCHES_KEY, "the content of 'Current menu status' does not match the content of '" + benchFileName + "'", "Current menu's status", benchFileName); if (diffFileName != null && !diffFileName.trim().equals("")) { try { StringUtils.writefile(diffFileName, differences); detail += " " + genericText.convert( GENStrings.SEE_DIFFERENCE_FILE, "\n\tPlease see difference in file '" + diffFileName + "'.", diffFileName); } catch (IOException e1) { String message = failedText.convert( FAILStrings.FILE_ERROR, "Can not write to " + diffFileName, diffFileName); Log.debug(debugmsg + message); } } componentExecutedFailureMessage(detail); return; } Log.debug(debugmsg + "All status of menu match that of benchfile."); String detail = genericText.convert( GENStrings.CONTENT_MATCHES_KEY, "the content of 'Current menu status' matches the content of '" + benchFileName + "'", "Current menu's status", benchFileName); componentSuccessMessage(detail); testRecordData.setStatusCode(StatusCodes.OK); }
@Override public boolean run(TestRun ctx) { String debugmsg = StringUtils.debugmsg(false); try { String tf = ctx.string("file"); ctx.log().info(debugmsg + "File parameter: " + tf); File target = new File(tf); if (!target.isAbsolute()) { String projectDir = null; try { projectDir = WDTestRun.getVariableValue(STAFHelper.SAFS_VAR_PROJECTDIRECTORY); if (projectDir != null && projectDir.length() > 0) { if (!projectDir.endsWith("/") && !projectDir.endsWith("\\")) { projectDir += File.separator; } if (tf.startsWith("/") || tf.startsWith("\\")) { tf = tf.substring(1); } tf = projectDir + tf; target = new File(tf); if (!target.isAbsolute()) { throw new IllegalArgumentException( "File parameter does not resolve to an absolute filepath."); } } else { throw new IllegalArgumentException( "Valid ProjectRoot not available and file parameter does not resolve to an absolute filepath."); } } catch (Exception x) { ctx.log().error(x.getClass().getSimpleName() + ", " + x.getMessage()); ctx.log() .error( debugmsg + "Filepath parameter must be absolute or relative to the Project: " + target.getPath()); return false; } } if (target.isFile()) { target.delete(); if (target.isFile()) { ctx.log() .error( debugmsg + "File exists and could not be deleted: " + target.getAbsolutePath()); return false; } } try { Files.createParentDirs(target); } catch (IOException io) { ctx.log().debug(debugmsg + io.getMessage() + ", attempted Files.createParentDirs..."); throw io; } Files.move(ctx.driver().getScreenshotAs(OutputType.FILE), target); return target.isFile(); } catch (NullPointerException np) { ctx.log() .error( debugmsg + "NullPointerException " + np.getMessage() + ", probably caused by missing FILEPATH parameter."); } catch (IOException io) { ctx.log().error(debugmsg + io.getClass().getSimpleName() + ", " + io.getMessage()); } return false; }
/** * <br> * <em>Purpose:</em> verifyProperty */ protected void verifyProperty() throws SAFSException { testRecordData.setStatusCode(StatusCodes.GENERAL_SCRIPT_FAILURE); if (params.size() < 2) { paramsFailedMsg(windowName, compName); return; } String prop = (String) iterator.next(); String val = (String) iterator.next(); String strcase = ""; boolean ignorecase = false; try { strcase = (String) iterator.next(); } catch (Exception x) {; } ignorecase = !StringUtils.isCaseSensitive(strcase); Log.info(".....CFComponent.process; ready to do the VP for prop : " + prop + " val: " + val); String rval = null; int status = sUtils.waitForObject(mapname, windowName, compName, 15); SGuiObject comp = null; String _type = null; if (status == 0) { comp = ((STestRecordHelper) testRecordData).getCompTestObject(); _type = ((STestRecordHelper) testRecordData).getCompType(); // TODO: Changed this! // rval = selenium.getEval("var xpath = \""+comp.getLocator()+"\";var prop = // \""+prop+"\";SAFSgetAttribute(xpath,prop);"); rval = sUtils.getAttribute(selenium, comp.getLocator(), prop); if (rval == null) { Log.info( "Selenium property '" + prop + "' for component '" + compName + "' of type '" + _type + "' not found. Trying alternatives..."); // assume attribute not found if (((_type.equalsIgnoreCase("CHECKBOX")) || (_type.equalsIgnoreCase("RADIOBUTTON"))) && (prop.equalsIgnoreCase("CHECKED")) && (val.equalsIgnoreCase("FALSE"))) { rval = "False"; } if (((_type.equalsIgnoreCase("LISTBOX")) || (_type.equalsIgnoreCase("COMBOBOX"))) && (prop.equalsIgnoreCase("SELECTED")) && (val.equalsIgnoreCase("FALSE"))) { rval = "False"; } } } Log.info( "Selenium property '" + prop + "' for component '" + compName + "' of type '" + _type + "' contains value '" + rval + "'"); // it is possible the property name is not valid for Selenium // it may be a property valid in a different engine // TODO: but do we want to assume we are running with other engines? if (rval == null || rval.equals("null")) { testRecordData.setStatusCode(StatusCodes.SCRIPT_NOT_EXECUTED); return; } if (((!ignorecase) && (val.equals(rval))) || (ignorecase && (val.equalsIgnoreCase(rval)))) { // set status to ok testRecordData.setStatusCode(StatusCodes.NO_SCRIPT_FAILURE); altText = genericText.convert( "bench_matches", compName + ":" + prop + " matches expected value \"" + val + "\"", compName + ":" + prop, val); log.logMessage(testRecordData.getFac(), altText, PASSED_MESSAGE); } else { // failed testRecordData.setStatusCode(StatusCodes.GENERAL_SCRIPT_FAILURE); altText = genericText.convert( "bench_not_match", compName + ":" + prop + " did not match expected result \"" + val + "\"", compName + ":" + prop, val); String detail = genericText.convert("actual_value", "ActualValue='" + rval + "'", rval); standardFailureMessage(altText, compName + ":" + prop + " " + detail); } }