zoukankan      html  css  js  c++  java
  • SAFS Distilled --- 9 April 2015 to 16 April 2015

    In the org.safs.model, the class Component stores:

    •  information of this component's name
    •  reference of its parent, also a component
    private String _name;
    private Component _parent;
    

    It provides interface to return its name, its parent's name and its parent's comopnent reference:

    public String getName();
    
    public Component getParent();   
    
    public String getParentName();
    

      

    In package org.safs.model, the Utils class provides various functions used by other classes. For example:

    /**
     * Wrap the provided val String in double-quotes.
     * @param val String to wrap in double-quotes
     * @return val wrapped in quotes or a double-quoted empty string if 
     * val was null.
     */
    static public String quote(String val) {
        if (val == null) return """";
            return """ + val + """;
    }   
    
    
    public static String concat(String string1, String string2) {
        return string1 + "&" + string2;
    }
    

    Retrieve SAFSVARS

    Let's first talk about the process of retrieving SAFS variables stored in SAFSVARS. This process will show many mechanisms routining in SAFS. We need to open up the packages of SAFS to know some basic classes structure.

    In package org.safs.model.tools, class EmbeddedHookDriverRunner is an access point to a minimalist EmbeddedHookDriver Driver API. EmbeddedHookDriver allows custom JSAFS test development and execution inside a Java-based SAFS Engine.

    As the constructor is:

    /**
     * Create the Runner that instantiates the particular EmbeddedHookDriver subclass 
     * pass in to the Constructor. 
     */
    public EmbeddedHookDriverRunner(Class clazz){
    	super();
    	if(driver == null){
    		try{				
    			driver = new EmbeddedHookDriverDriver(clazz);
    		}catch(Exception x){
    			x.printStackTrace();
    			throw new Error("Cannot instantiate required Drivers!");
    		}
    	}
    }
    

    It'll create specific subclass of EmbeddedHookDriver for doing the work. Also from the code, we can know that EmbeddedHookDriverDriver is just a wrapper of EmbeddedHookDriver for providing minimalist interface.

                                  

    Java-based SAFS Engines would need to implement an engine-specific subclass of this EmbededHookDriver using a EmbeddedHookSTAFHelper to take advantage of this feature. For example:

    EmbeddedHookDriverSubclass hook = new EmbeddedHookDriverSubclass("UniqueName");
    

    Generic JavaHook for tool-independent SAFS Engines. This abstract class provides the implementation for the initialization and event handling of all Java-based SAFS Engines that will be controlled via our SAFS protocols.

    // Set the process name for this hook for an instance of created from an empty constructor.
    protected void setProcessName(String process_name);
    
    // Insert this SAFS Engine hook into the STAF system.
    void start();
    

    JSAFSDriver Structure and Utility:

                    

    • AbstractDriver: the root, abstract implementation of tool-independent driver.
    • DefaultDriver: root, yet abstract, implementation of tool-independent driver, final concrete implementation must implement AbstractDriver#processTest().
    • JSAFSDriver: provides easy access to SAFS functionality for non-SAFS programs and frameworks.

    Combine the two parts, we get:

               

    In order to retrieve the value of a SAFS variable stored in SAFSVARS, SAFS uses a embeddedHookDriverRunner to finish the work.

    return Runner.jsafs().getVariable(variableName);
    

    The steps are:

    1. return a EmbeddedHookDriver by using EmbeddedHookDriverDriver called by EmbeddedHookDriverRunner.
    2. use this embeddedHookDriver to return a JSAFSDriver.
    3. use the JSAFSDriver to retrieve the value of a SAFS variable stored in SAFSVARS.

    Then, let's focus on the retrieving method of JSAFSDriver.

    The method getVariable()

    public String getVariable(String varname){		
    	return getVarsInterface().getValue(varname);
    }
    

    is from the superclass AbstractDriver. It'll return the VarsInterface:

    In the interface SimpleVarsInterface, it will return the current value of variable var.

    That's the whole process of retrieving the variables stored in SAFSVARS.

    The obvious next question is: when are the values of variables stored in SAFSVARS loaded into program?

    Well, in fact this will be another long story we will expand below.

    In order to know when SAFS load the configuration information, we'll focus on the following class structure:

                          

    In the AbstractDriver class, it offers lots of variables to store the driver interface information:

    // Driver Interface Information	
    protected InputInterface           input       = null;
    protected MapsInterface            maps        = null;
    protected VarsInterface            vars        = null;
    protected LogsInterface            logs        = null;
    protected CoreInterface            core        = null;
    protected CountersInterface        counts      = null;	
    protected DebugInterface           debug       = new DebugInfo();
    

    Here, we may focus just one variable maps (which) as our example for explanation. 

    The JSAFSDriver offers a method run() for initializing the embedded dirvers and engines to start running if it is not already running. It ensures the drivers are initialized before trying to use them. Following this run() method, a series of calling will happen:

    1. driver.run()
    2. preloadAppMapExpressions()
    3. preloadAppMap()

    The  first part, driver.run(), will initialize configuration with default paramters. The process is below:

            

    Thus, the validateRootConfigureParameters() method will configurate paramters with defalut paramters.

    • In DefaultDriver class, method validateRootConfigureParameters() gets the configuration information.

    • In org.safs.tools.drivers.ConfigureFile.java, class ConfigureFile implements ConfigureInterface, and its method getNamedValue() will retrieve the values in the configuration sources.

    • In org.safs.tools.drivers.ConfigureInterface.java, the method getNamedValue() of interface ConfigureInterface is used to retrieve an item that may be in the configuration sources. An item is identified by a parent key or section name, like in an INI file "section", and the name of the item in that section.

    After loading of configuration information, in the DefaultDriver class, the function initializeRuntimeInterface() will initialize these interface variables:

    protected void initializeRuntimeInterface(){
    	// ...
    	try {
    		// first one in, if initializing STAF, must be last one to shutdown.
    		maps = (MapsInterface) getGenericInterface(DriverConstant.SECTION_SAFS_MAPS,
    													 DriverConstant.DEFAULT_MAPS_INTERFACE);
    		// ...
    	}
    	// ...
    }

    Inside the getGenericInterface() method, it'll use the configuration information, stored in variable configInfo, to initialize the corresponding interface information, i.e. maps here:

    protected GenericToolsInterface getGenericInterface (String configSection, String defaultInterface) 
    	throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    	String iName = configInfo.getNamedValue(configSection, "Item");
    	if (iName == null) 
    		iName = defaultInterface;
    	iName = StringUtilities.TWhitespace(iName);
    	iName = StringUtilities.removeDoubleQuotes(iName);
    	return ((GenericToolsInterface) (Class.forName(iName).newInstance()));
    }
    

    The third part, preloadAppMap(), will locate the directory of MAP file, and using file read function to assign corresponding interface variables:

                           

    That's the brief explanation of loading MAP files.


    Open a Browser

    In the SeleniumPlus class, the command() method executes a driver command by a EmbeddedDriverRunner, Runner:

    public static EmbeddedHookDriverRunner Runner = new EmbeddedHookDriverRunner(EmbeddedSeleniumHookDriver.class);
    // ...
    prevResults = Runner.command(command, params);
    

    Process of calling functions:

                   

     In order to startup a service, it needs to use the interface of a driver's wrapper, i.e. the Runner. Then, by using the method of wrapper, it uses JSAFSDriver to call corresponding method. It's obvious that all the other service calling will get through this process. Summary above, we get:

    1. Use an access point of a driver's wrapper, Runner.
    2. Use the wrapper, driver of EmbeddedHookDriver which is the field of Runner, driver.
    3. Use this driver to get a Java SAFS Driver, jsafs.
    4. Use jsafs to call process command methods.

    Following above steps, by using jsafs to startup command methods, it needs to call abstract driver method. After the initial parameters processing, it will use a Process variable, proc, to call the concrete driver methods.

    The RemoteDriver class handle a SeleniumRMIAgent, if enabled, to communicate with a remote SAFS Selenium RMI Server.


    Log In

    The log in process involves the click action, which is a little different than the process of command.

    Process of calling structure:

    In ComponentFunction class, the componentProcess() method includes the process generic actions on a component.


    Set Text Value

    The process of "set text value":

    How to generate Map.class file:

  • 相关阅读:
    获取Android控件宽高
    Android面试题:大图加载,防止OOM
    Android面试题:讲一讲Glide的原理
    面试题:实现一个容器,提供两个方法,add,size;写两个线程,线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数到5个时,线程2给出提示并结束
    Java线程中断的三种方法
    Java的四种引用:强引用、软引用,弱引用和虚引用
    Bellman-Ford(可解决负权边)--时间复杂度优化
    【Leetcode 动态规划、深度优先搜索】不同路径(62)、 不同路径 II(63)、不同路径 III(980)
    ElasticSearch scroll分页查询
    MySQL Myisam引擎和Innodb引擎的区别
  • 原文地址:https://www.cnblogs.com/kid551/p/4409017.html
Copyright © 2011-2022 走看看