Java SAFS Framework Interface

by Carl Nagle
Last Updated: 04/28/2016 10:44:0804/09/2015 15:27:2009/26/2014 02:24:30

This represents the proposed Java interface for Tool-Independent Drivers and Engines.

See also: SAFS Framework, JSAFS Design, JSAFS Javadoc, SAFS Driver Development, SAFSDEV Project


The intention of all the following framework interfaces is to insulate any Driver, and any compatible Java Client--even a SAFS Engine--from interfacing directly with the implementation. This allows the underlying implementation to be completely changed, enhanced, or user-defined and subclassed as desired. For example, SAFSVARS and SAFSMAPS might be implemented by some mechanism other than STAF in some implementations. Our test tables could come from files, database servers, or humans typing into a manual test GUI. The same Driver could be used in all of these cases.

That is the goal. We are coding the tool-independent Driver (TID) to take advantage of these interfaces. However, the existing SAFS/RobotJ and SAFS/DriverCommands engines will need to be refactored to fully realize this capability. These engines are currently hardcoded to use our STAF services through specific classes. This engine refactoring, however, should not be too extreme, but is not part of the current Driver effort. The Driver will use the concrete implementations that talk with STAF, but the engines will talk with STAF directly until they are refactored.


Tools Interfaces

These interfaces generally allow us to categorize a tool, and provide a simple interface to launch, reset, and shutdown the various tools through a common API.


SAFSVARS Interface

Our default, concrete org.safs.tools.vars.SAFSVARS implementation simply wraps our existing SAFSVARS STAF service. Each method in the class will simply be the appropriate STAF call to the running SAFSVARS service--just like any other client that wants to use SAFSVARS. Yet, this insulates any Driver/Client from talking with STAF directly and allows for alternative implementations and custom enhancements.

To accomplish this interface with STAF, the implementation will need to use org.safs.staf.STAFProcessHelpers to obtain an instance of a org.safs.STAFHelper specific for the Driver process. All concrete classes used for and by the Driver will talk to STAF using the same process name/id. The class will communicate with the running STAF service through the STAFHelper. (A review of STAFHelper shows it looks pretty ugly, and may need some refactoring. Definitely it needs more documentation.)

The launchInterface(Object) call required from the ConfigurableToolsInterface would be tasked with verifying the SAFSVARS service is running, or launching the SAFSVARS service if it is not already running. This may be tempered by AUTOLAUNCH=FALSE settings provided in the configuration file. Configuration information is accessible through the DriverInterface object passed to the launchInterface function, or via System Properties set with command-line arguments when the Driver was launched.

The shutdown() call required from the ConfigurableToolsInterface would be used to close down the SAFSVARS service through STAF, but it should only do this if it was the call to launchInterface that started the service. shutdown() should not stop the service if it was already running prior to the call to launchInterface.


SAFSMAPS Interface

Our default, concrete org.safs.tools.input.SAFSMAPS implementation simply wraps our existing SAFSMAPS STAF service. Each method in the class will simply be the appropriate STAF call to the running SAFSMAPS service--just like any other client that wants to use SAFSMAPS. Yet, this insulates any Driver/Client from talking with STAF directly and allows for alternative implementations and custom enhancements.

To accomplish this interface with STAF, the implementation will need to use org.safs.staf.STAFProcessHelpers to obtain an instance of a org.safs.STAFHelper specific for the Driver process. All concrete classes used for and by the Driver will talk to STAF using the same process name/id. The class will communicate with the running STAF service through the STAFHelper.

The launchInterface(Object) call required from the ConfigurableToolsInterface would be tasked with verifying the SAFSMAPS service is running, or launching the SAFSMAPS service if it is not already running. This may be tempered by AUTOLAUNCH=FALSE settings provided in the configuration file. Configuration information is accessible through the DriverInterface object passed to the launchInterface function, or via System Properties set with command-line arguments when the Driver was launched.

The shutdown() call required from the ConfigurableToolsInterface would be used to close down the SAFSMAPS service through STAF, but it should only do this if it was the call to launchInterface that started the service. shutdown() should not stop the service if it was already running prior to the call to launchInterface.


SAFSLOGS Interface

Our default, concrete org.safs.tools.logs.SAFSLOGS implementation simply wraps our existing SAFSLOGS STAF service. Each method in the class will simply be the appropriate STAF call to the running SAFSLOGS service--just like any other client that wants to use SAFSLOGS. Yet, this insulates any Driver/Client from talking with STAF directly and allows for alternative implementations and custom enhancements.

To accomplish this interface with STAF, the implementation will need to use org.safs.staf.STAFProcessHelpers to obtain an instance of a org.safs.STAFHelper specific for the Driver process. All concrete classes used for and by the Driver will talk to STAF using the same process name/id. The class will communicate with the running STAF service through the STAFHelper.

The launchInterface(Object) call required from the ConfigurableToolsInterface would be tasked with verifying the SAFSLOGS service is running, or launching the SAFSLOGS service if it is not already running. This may be tempered by AUTOLAUNCH=FALSE settings provided in the configuration file. Configuration information is accessible through the DriverInterface object passed to the launchInterface function, or via System Properties set with command-line arguments when the Driver was launched.

The shutdown() call required from the ConfigurableToolsInterface would be used to close down the SAFSLOGS service through STAF, but it should only do this if it was the call to launchInterface that started the service. shutdown() should not stop the service if it was already running prior to the call to launchInterface.

The implementation needs to take into consideration whatever Remote Logging capabilities we already support with our SAFSLOGS service to insure these continue to be supported.


SAFSINPUT Interface

The default. concrete tools.input.SAFSINPUT provides our interface to the SAFSINPUT STAF service.

Actual processing of test records happens in the Driver. The only exception will be that the current SAFSTextFile file reading class already knows how to skip blank lines and comment lines. Thus, it is able to skip those until it finds a real test record to send to the Driver. The SAFSINPUT Service command to OPEN a new file should accept optional parameters that allow us to enable those line-skipping features.

That tells the Driver we are looking for a Suite level test table--a file--with the default Suite level file extension (.STD) in the current default or "Datapool" directory.

But the following lines should also locate the exact same file, and the Driver or the SAFSINPUT Class or the SAFSINPUT Service needs to accomodate all these:

The existing STAF SAFSTextFile implementation pretty much encapsulates the way the desired file reading should work. Each SAFSTextFile class handles working with one file and that is all it knows about. The SAFSINPUT STAF service handles the instantiation of these SAFSTextFile classes and routes incoming STAF service requests to the appropriate instance. The individual file readers shouldn't know anything about Cycles, Suites, or Steps--they are just forwarding records from the file they were told to play with. They have no idea what it is going to be used for. It is the Driver that handles which inputs are at what test level.

Like our SAFSMAPS, SAFSLOGS, and SAFSVARS wrapper classes; the launchInterface(Object) call required from the ConfigurableToolsInterface would be tasked with verifying the SAFSINPUT service is running, and perhaps even launching the SAFSINPUT service if this is applicable. This may be tempered by AUTOLAUNCH=FALSE settings provided in the configuration file. Configuration information is accessible through the DriverInterface object passed to the launchInterface function, or via System Properties set with command-line arguments when the Driver was launched.


Driver Interface

The DriverInterface is primarily provided for use by the other tool interfaces. ConfigurableToolsInterface objects require access to configuration information or even other tools to perform their functions. The DriverInterface provides a centralized access-point for gaining access to most configuration information, or other required tools.

Of key importance, is that the Driver will provide access to the critical ConfigureInterface instance. This allows configurable tools to retrieve configuration information from external sources (like configuration files, etc.).

Our default, concrete org.safs.tools.drivers.SAFSDRIVER is currently designed as a standalone, Java application or class that will be launched into its own JVM. As it currently is designed, there is no GUI associated with the Driver. It is strictly a "run the specified test" class. Though it is easy to envision some optional GUI front-end that will allow the user to interactively specify test configuration information and parameters and then launch the Driver from there.


SAFSDRIVER Command Line Options

Command Line Options:
-Dsafs.driver.name=String
Unique name or ID for the driver instance. Can also be specified in the Config Source. A default value should exist in the Driver if none is provided.

-Dsafs.driver.root=fullpath
System property for the root driver directory. Points to the system-wide "safstid.ini" configuration file directory. (As opposed to any project-specific "safstid.ini" file located in the root project directory.)

-Dsafs.project.root=fullpath/directoryname
System property for the root project directory. An optional project-specific "safstid.ini" file will be sought here if one is not identified through command-line options.
If not provided, and other settings do not allow this to be deduced, then the current Working Directory might be assumed.
A single directory name instead of fullpath can be provided if running from a JAR file intending to automatically extract the project at runtime. The directory name will be sought as a root directory in the JAR file.

-Dsafs.project.extract=fullpath
System property for the root directory in which to extract a project structure from a JAR or ZIP file during runtime execution via JAR file.
If not specified, a Temp directory will be created using the -Dsafs.project.root as the root directory in Temp.

-Dsafs.config.locator=classname
System Property identifying an alternate class to locate driver configuration information. The class is required to implement the "org.safs.tools.drivers.ConfigureLocatorInterface"
Default Locator: "org.safs.tools.drivers.ConfigureFileLocator"

-Dsafs.driver.config=string|path
System Property identifying the path to an alternate driver configuration file (other than safstid.ini in the driver root location.

-Dsafs.project.config=string|path
System Property identifying the path to an alternate project configuration file (other than safstid.ini in the default project config location.
In most cases, if not specified then "test.ini" may be assumed.

-Dsafs.driver.autolaunch=TRUE|FALSE

-Dsafs.test.name=string|path

-Dsafs.test.level=CYCLE|SUITE|STEP
Optional if the test level can be accurately determined from the filename extension. (.CDD, .STD, .SDD)
-Dsafs.test.millisbetweenrecords=N
System property for Driver Delay millisBetweenRecords. Defaults to 100 millis.

-Dsafs.test.numlockon=true|false
System property for turning on/off the keyboard number lock before testing.

-Dsafs.test.unexpected_alert_behaviour=accept|dismiss|ignore|off
System property for how to handle the unexpected alert automatically. Defaults to ignore.
accept -> "OK"; dismiss -> "Cancel"; ignore -> "keep Alert"; off -> "don't set this".

-Dsafs.test.defaultmap=mapid

-Dsafs.test.dnd.release.delay=N
System property for the delay in milliseconds before releasing the mouse

-Dsafs.step.separator=string (1 char)
Only the setting for the test level of the provided test name is required.

-Dsafs.suite.separator=string (1 char)
Only the setting for the test level of the provided test name is required.

-Dsafs.cycle.separator=string (1 char)
Only the setting for the test level of the provided test name is required.

-Dsafs.log.level=ERROR|WARN|PASS|GENERIC|INDEX|INFO|DEBUG
The default log level is GENERIC.

-Dsafs.log.overwrite=TRUE|YES|1 (anything else is FALSE)
The default log overwrite is FALSE.

-Dsafs.log.capxml=TRUE|YES|1 (anything else is FALSE)
The default log capxml is FALSE.

-Dsafs.log.truncate=TRUE|YES|ON|numChars (anything else is FALSE)
Enable log message truncation at numChars length (Default length: 128).

-Dsafs.step.logname=logid|name
The primary logname used for capturing all test information.

-Dsafs.suite.logname=logid|name
Only needed if a separate log is used to capture Suite information.

-Dsafs.cycle.logname=logid|name
Only needed if a separate log is used to capture Cycle information.

-Dsafs.step.logmode=TEXTLOG|CONSOLELOG|XMLLOG|TOOLLOG|ALL
Specifies which log formats are to be initialized/enabled for the primary log.

-Dsafs.suite.logmode=TEXTLOG|CONSOLELOG|XMLLOG|TOOLLOG|ALL
Required only if a safs.suite.logname has been specified. Specifies which log formats are to be initialized/enabled for this log.

-Dsafs.cycle.logmode=TEXTLOG|CONSOLELOG|XMLLOG|TOOLLOG|ALL
Required only if a safs.cycle.logname has been specified. Specifies which log formats are to be initialized/enabled for this log.

-Dsafs.log.accept.slf4j.debug=true|false
If the debug message from slf4j will be output to SAFS debug log file

-Dsafs.log.accept.slf4j.test=true|false
If the test message from slf4j will be output to SAFS test log file

-Dsafs.rest.auth=config\auth2.xml
Defines file (relative to project or absolute) holding the authorization/authentication information for REST testing.

-Dsafs.rest.proxy=proxy.host.name:port
Defines the proxy information (proxy-server and port) for REST testing.

-Dsafs.selenium.server.jvm=pathToJVMExecutable
Indicates the JVM to start the SELENIUM server, ex: C:\SeleniumPlus\Java64\jre\bin\java.exe

-Dsafs.selenium.server.jvm.options=JVM options
Indicates the JVM Options for the SELENIUM server to start with, ex: -Xms256m -Xmx1g

-Dsafs.selenium.server.jvm.xmx=2g (Default: 2g)
Indicates the maximum memory to use for the SELENIUM server.

-Dsafs.selenium.server.jvm.xms=256m (Default: 512m)
Indicates the minimum memory to use for the SELENIUM server.

-Dselenium.host=hostname (Default: localhost)
Indicates on which machine the selenium server is going to run.

-Dselenium.port=N (Default: 4444)
Indicates on which port the selenium server is going to run.

-Dselenium.node=nodesInforamtion
Indicates selenium nodes information, such as node1.host:node1.port;node2.host:node2.port

-Dsafs.selenium.console.state=MAX|MIN|NORMAL
Specifies the selenium server's console state.

-Dsafs.selenium.web.drivers=explorer:chrome:MicrosoftEdge
Defines specific drivers (separated by colon :) to start with the selenium server. By default, IE, Chrome, Firefox and MicrosoftEdge drivers will start up with the selenium server.

-Dsafs.selenium.connection.test.command= one of selenium-driver-command (Default is getAlertText)
Specifies the command to test the connection between WebDriver and BrowserDriver.

-Dsafs.selenium.connection.test.max.duration=Time in milliseconds (Default is 5000)
Specifies the maximum duration (in milliseconds) that user can accept when executing command defined by safs.selenium.connection.test.command

-Dsafs.selenium.connection.test.max.try=Number (Default is 2)
Specifies the maximum times to try to get a good connection between WebDriver and BrowserDriver

-Dsafs.selenium.delay.get.content=Time in milliseconds (Default is 0)
Specifies the delay (milliseconds) waiting for the refresh of a webelement before getting its content

-Dsafs.selenium.timeout=Time in seconds (Default is 0)
Specifies the timeout in seconds before the selenium hub automatically releases a node that hasn't received any requests for more than the specified number of seconds

-Dsafs.selenium.browser.timeout=Time in seconds (Default is 0)
Specifies the timeout in seconds a selenium node is willing to hang inside the browser

-Dsafs.selenium.bypass.frame.reset=True | False (Default is False)
By default, search algorithms begin every search by switching back to the topmost root HTML document (frame). Set it to true if you wish to disable this frames reset at the beginning of every component search. But you need to handle the frame-switch by yourself.

-Dsafs.selenium.bypass.robot.action=True | False (Default is False)
By default, we firstly use Java Robot to do the automation, user can bypass the "Java Robot" and use the selenium directly to do the automation.

-Dsafs.selenium.rmi.port.forward=True | False (Default is False)
With docker, by default, our library will connect the RMI server running on docker container by container's IP and port. But we can map the container's port to local-machine's port so that our library will connect the RMI server (running on docker container) by "localhost" and the mapped port.

-Dsafs.selenium.registry.port=number (Default is 1099)
Specify the port to get the registry for looking up the RMI server.

-Dsafs.test.product.name=Product to test
Specifies the name of the product the test runs against

-Dsafs.test.product.platform=OS platform
Specifies the platform on which the test runs

-Dsafs.test.product.track=track name
Specifies the track of the product the test runs against

-Dsafs.test.product.branch=branch name
Specifies the branch of the product the test runs against

Enhancements, corrections, and more detail will be added as necessary.


SAFSDRIVER Configuration File Options

The default name of the configuration file is "safstid.ini".
This file is readable by Windows AND Java classes. Items commented out with semicolons tell the DRIVER to use its pre-programmed default values, or items passed in via command-line arguments. Multiple configuration files can be used in a chain with values in one file overriding or masking values in another file. The default priority of the chain is:

  1. Command-Line Parameters
  2. Explicitly named PROJECT Configuration File
  3. Default PROJECT Configuration File
  4. Explicitly named DRIVER Configuration File
  5. Default DRIVER Configuration File

For space conservation, items are shown in 3 columns below. A real configuration file will only have one entry per line in a single column format.

[SAFS_VARS]
AUTOLAUNCH=TRUE
;Item=Alt VarsInterface Class
;ServiceClass=Alt Service Class
;ServiceClass=org.safs.staf.service.var.EmbeddedVariableService
;Service=Alt Service Name
;Options=
;EmbedVars=TRUE

[SAFS_MAPS]
AUTOLAUNCH=TRUE
;Item=Alt MapsInterface Class
;ServiceClass=Alt Service Class
;ServiceClass=org.safs.staf.service.map.EmbeddedMapService
;Service=Alt Service Name
;Options=

[SAFS_LOGS]
AUTOLAUNCH=TRUE
OVERWRITE=TRUE
CAPXML=TRUE
TRUNCATE=ON|numChars
;Item=Alt LogsInterface Class
;ServiceClass=Alt Service Class
;ServiceClass=org.safs.staf.service.logging.EmbeddedLogService
;Service=Alt Service Name
;Options=
;= accept.slf4j.debug and accept.slf4j.test are used to turn on/off
;= the switch to write message from slf4j to SAFS debug/test log file.
;accept.slf4j.debug=true|false
;accept.slf4j.test=true|false

[SAFS_INPUT]
AUTOLAUNCH=TRUE
;Item=Alt InputInterface Class
;ServiceClass=Alt Service Class
;ServiceClass=org.safs.staf.service.input.EmbeddedInputService
;Service=Alt Service Name
;Options=

[SAFS_ENGINES]
First=org.safs.tools.engines.SAFSROBOTJ
Second=Classname
Third=Classname
Fourth=Classname
Fifth=Classname
Sixth=Classname
Seventh=Classname
Eighth=Classname
Ninth=Classname
Tenth=Classname

[SAFS_DROID]
AUTOLAUNCH=FALSE
DROIDPROJECT=C:\SAFS\samples\Droid
CONSOLE2DEBUG=True
SHUTDOWNDELAY=10
;EMULATOR_AVD="SprintEVO"
;PersistEmulators=False
;PersistJVM=False
;DeviceSerial=serial number
ANDROID-SDK=Android SDK Root Dir
ANDROID-TOOLS=Android SDK Tools Dir
FORCECLOSE=True
FORCESTOP=True
FORCECLEAR=True
TCPMessengerAPK=path to TCP Messenger APK
;TCPMessengerPackage="org.safs.android.messenger"
TestRunnerAPK=path to TestRunner APK
;TestRunnerPackage="org.safs.android.engine"
;TestRunnerSource=path to TestRunner project
;TestInstrument=from AndroidManifest.xml
TargetAPK=path to Target APP APK
TargetResignJar=path to re-sign.jar
;TargetPackage="com.example.android.apis"
AntRebuildArgs="-noclasspath"
AntRebuildForce=True
PortForwarding=True
;HOOK=org.safs.android.DJavaHook
;TIMEOUT=120
;STAFID="SAFS/DROID"
;JVM=JVMpath
;JVMARGS=JVM Args
;CLASSPATH=altClasspath
;XBOOTCLASSPATH=<CLASSPATH>

[SAFS_IOS]
AUTOLAUNCH=FALSE
Project=/Library/SAFS/samples/UICatalog/
Template="UICatalogInstruments.tracetemplate"
;HOOK=org.safs.ios.JavaHook
;TIMEOUT=30
;STAFID="SAFS/IOS"
;JVM=JVMpath
;JVMARGS=JVM Args
;CLASSPATH=altClasspath
;XBOOTCLASSPATH=<CLASSPATH>

[SAFS_REST]
;= AUTH holds the authorization/authentication
;= file (relative to project or absolute) for REST testing
AUTH=config\auth2.xml
;= PROXY holds the proxy information for REST testing
PROXY=proxy.host.name:port

[SAFS_TC]
AUTOLAUNCH=FALSE
HOOK="C:SAFS\TCAFS\TCAFS.VBS"
;TIMEOUT=45
;SuiteName="C:\Path\To\AProject.pjs"
;ProjectName="ProjectName"
;ScriptName="StepDriver"
;OPTIONS="/customArg:value /Another"
;ConvertSAFSInputKeysSyntax=True|False
;ConvertSAFSItemPathSyntax=True|False
;SECSWaitForWindow=30
;SECSWaitForComponent=30
;TFSMOnly=True|False
;DepthLevel=25

[SAFS_ROBOTJ]
AUTOLAUNCH=TRUE
DATASTORE=<FullPathTo>\RFTProjectDir
;ClearProxiesAlways=True|False
;TIMEOUT=45 (launch timeout)
;SECSWaitForWindow=30
;SECSWaitForComponent=30
;TESTDomains=Html,Net,Java,Win,Flex,SWT
;CommandLineBreakpoint=True|False
;STAFID="SAFS/ROBOTJ"
;JVM=altJVMpath\java.exe
;JVMARGS="-Xms512m -Xmx1024m"
;CLASSPATH=altClasspath
;INSTALLDIR=<wswpluginPath> pre-RFT V7
;JARPATH=<FullPathTo>rational_ft.jar  RFT V7+
;PROJECTPATH=<RFT V7+ CLASSPATH>
;XBOOTCLASSPATH=<Classpath>
;PROJECT=<Project.rsp>
;BUILD=<Build #>
;PLAYBACK=TestScript
;LOGFOLDER=Default
;LOG=TestScript
;USERID=<userid>
;PASSWORD=
;OPTIONS=
;RFSMOnly=True|False
;RFSMCache=True|False
;DynamicEnableTopWindows=True|False

[SAFS_SELENIUM]
AUTOLAUNCH=FALSE
;JVM=JVMPath to Java 1.5 or higher
;CLASSPATH=altClasspath
;= GATEWAYHOST and GATEWAYPORT are used
;= to connect internet
GATEWAYHOST=yourCorpGateway.net
GATEWAYPORT=80

;= Settings for Selnium1.0
;HOOK=org.safs.selenium.SeleniumJavaHook
;BROWSER=*piiexplore | *firefox | *iexplore
;DEBUGLOG=<fullpathTo>/SeleniumDebug.out

;= Settings for Selnium2.0 WebDriver
;HOOK=org.safs.selenium.webdriver.SeleniumHook
;BROWSER=explorer | firefox | chrome
PROXY_BYPASS_ADDRESS=localhost,127.0.0.1,host.not.thru.gateway
BROWSER_REMOTE=false|true
;= Selenium Server Settings
;= SELENIUMHOST and SELENIUMPORT are used
;= to connect the Selenium Server (standalone or hub)
;SELENIUMHOST=remote.server.com
;SELENIUMPORT=4444
;= SELENIUMNODE defines the selenium nodes to run.
;= If SELENIUMNODE is given, SELENIUMHOST will start
;= as a selenium hub; otherwise as a stand-alone server.
;SELENIUMNODE=node1:port:config1;node2:port:config2
;= SELENIUMSERVER_JVM_OPTIONS is JVM options
;= for starting the Selenium Server
;SELENIUMSERVER_JVM_OPTIONS=-Xmx1g -Xms512m -Xdebug
;= SELENIUMERVER_JVM_Xmx and SELENIUMERVER_JVM_Xms 
;= specify the value of JVM options -Xmx and -Xms 
;= for the Selenium Server, it will override
;= the default value or the value specified 
;= in SELENIUMSERVER_JVM_OPTIONS
;SELENIUMSERVER_JVM_Xmx=4g (default: 2g)
;SELENIUMSERVER_JVM_Xms=256m (default: 512m)
;SELENIUMSERVER_JVM=fullpath\java.exe (default: 1.7.0_45 64bit)
;= CONSOLE_STATE is used to set the state of
;= Selenium Server Console
;CONSOLE_STATE=MIN|MAX|NORMAL
;= WEB_DRIVERS is used to set the specific browser
;= drivers (separated by colon :) to start with the selenium server. 
;= IE, Chrome, Firefox and MicrosoftEdge drivers will be started by Default.
;WEB_DRIVERS=explorer:chrome:MicrosoftEdge
;connection.test.command specifies the command to 
test the connection between WebDriver and BrowserDriver.
;connection.test.command=selenium-driver-command (Default:getAlertText)
;connection.test.max.duration specifies the maximum duration
(in milliseconds) that user can accept when executing command 
defined by connection.test.command
;connection.test.max.duration=Time in milliseconds(Default: 5000)
;connection.test.max.try specifies the maximum times to try
to get a good connection between WebDriver and BrowserDriver
;connection.test.max.try=Number(Default: 2)
;delay.get.content specifies the delay (milliseconds) waiting for the 
refresh of a webelement before getting its content
;delay.get.content=Time in milliseconds(Default: 0)
;timeout in seconds before the hub automatically releases a node
that hasn't received any requests for more than the specified number of seconds.
;timeout=Time in seconds(Default: 0)
;timeout in seconds a selenium node is willing to hang inside the browser.
;browser.timeout=Time in seconds(Default: 0)
;By default, search algorithms begin every search by switching back to 
;the topmost root HTML document (frame). Set it to true if you wish to 
;disable this frames reset at the beginning of every component search.
;But you need to handle the frame-switch by yourself.
;bypass.frame.reset=True | False(Default: False)
;By default, we firstly use Java Robot to do the automation,
user can bypass the "Java Robot" and use the selenium directly to do the automation.
;bypass.robot.action=True | False(Default: False)
;With docker, by default, our library will connect the 
RMI server running on docker container by container's IP and port. But we can map 
the container's port to local-machine's port so that our library will connect 
the RMI server (running on docker container) by "localhost" and the mapped port.
;rmi.port.forward=True | False(Default: False)
;Specify the port to get the registry for looking up the RMI server.
;registry.port=port number(Default: 1099)


[SAFS_DRIVERCOMMANDS]
AUTOLAUNCH=TRUE
;STAFID="SAFS/DRIVERCOMMANDS"
;JVM=JVMPath
;CLASSPATH=altClasspath
;Hook=String/Classname
;Options=LOG

;= OUT_MAILXXX is Mail setting
;OUT_MAILSERVER="mail server"
;OUT_MAILSERVERPORT=25|465|587
;OUT_MAILSERVERPROTOCOL=SMTP|SMTPS|TLS
;OUT_MAILUSER=user.name@mail.com
;OUT_MAILPASS=user.password

[SAFS_QTP]
AUTOLAUNCH=FALSE
HOOK=C:\PathTo\QTP.VBS
;Hook=C:\PathTo\AnyExecutable.ext
;TIMEOUT=45

[STAF]
;NOSTAF=TRUE
;EmbedDebug=<filepath>
PATH=Path to/STAFProc.exe
CONFIG=Path to/staf.cfg
;EmbedSEM=TRUE
;EmbedQUEUE=TRUE

[SAFS_DRIVER]
DriverName=String
DriverRoot=String/DriverRootPath
BringMonitorToFrontOnPause=True|False
TurnOnPOF=True|False
TurnOnPOW=True|False
ResolveSkippedRecords=True|False
;ShowMonitor not sought by all Drivers
ShowMonitor=True|False

[SAFS_PROJECT]
ProjectName=ProjectName
ProjectRoot=String/ProjectRootPath

[SAFS_TEST]
;TestName=String/Path
;TestLevel=CYCLE|SUITE|STEP
;DefaultMap=String
;CycleSeparator=","
;CycleSuffix=".CDD"
;SuiteSeparator=","
;SuiteSuffix=".STD"
;StepSeparator=","
;StepSuffix=".SDD"
;LogLevel=String
;StepLogName=SAFSLOG
;StepLogMode=TEXTLOG|CONSOLELOG|XMLLOG|TOOLLOG|ALL
;SuiteLogName=SAFSLOG
;SuiteLogMode=TEXTLOG|CONSOLELOG|XMLLOG|TOOLLOG|ALL
;CycleLogName=SAFSLOG
;CycleLogMode=TEXTLOG|CONSOLELOG|XMLLOG|TOOLLOG|ALL
;millisBetweenRecords=N  (default: 0)
;secsWaitForWindow=N     (default: 30)
;secsWaitForComponent=N  (default: 30)
;numLockOn=TRUE|FALSE
;UnexpectedAlertBehaviour ONLY works for Selenium2.0 webdriver engine for now
accept -> "OK"; dismiss -> "Cancel"; ignore -> "keep Alert"; off -> "don't set this".
;UnexpectedAlertBehaviour=accept|dismiss|ignore|off (default: ignore)
;DndReleaseDelay=N  (default: 800 millisecond)
;ProductName, Platform, Track and Branch are orderable information.
;ProductName=Product to test
;Platform=OS platform
;Track=Product track
;Branch=Product branch

[SAFS_DIRECTORIES]
;DATADIR=Datapool
;BENCHDIR=Datapool/Bench
;DIFFDIR=Datapool/Dif
;LOGDIR=Datapool/Logs
;TESTDIR=Datapool/Test

[SAFS_DIFFER]
;TOOL_EXE=DIFF.EXE
;TOOL_OPTIONS="--text -s -y"
;TOOL_BINARY_OPTIONS="--binary -s"

[SAFS_DIFFVIEWER]
;TOOL_EXE=GEMINI.EXE
;TOOL_OPTIONS=" "

[SAFS_OCR]
;OCRName=TOCR|GOCR (default:TOCR)
;LanguageID=chi|zh|eng|en|jpn|jp|kor|kr|fra|fr
;(default:system language; only en is support so far)

[SAFS_IBT]
;UseMultiThreadSearch=True|False (default:False)
;When UseMultiThreadSearch is true,
;ThreadNumber can be adjusted for best search performance.
;ThreadNumber=N (default:4)
;UsePerImageModifiers=True|False (default:False)

Enhancements, corrections, and more detail will be added as necessary.


Configure Interface

A ConfigureInterface generally represents the need to read a configuration source. Although the source is not required to be in a Windows INI file format, the interface reflects this format convention. The interface reflects name=value pairs that can be separated into named secions. Other implementations are possible as long as the API conforms to the documented interface.

Note the "add" and "insert" methods allow configuration information to be "chained". The parent ConfigureInterface object will maintain storage of any number of other ConfigureInterface objects. The parent ConfigureInterface object is expected to search all stored objects, usually in a documented order (first-in first, or last-in first), to try to locate the requested configuration setting. This allows test-specific or project-specific values to override stored global or machine-specific settings and for all of this to be resolved in a single call to the held ConfigureInterface.

ConfigurableToolsInterface classes will often require either a reference to the Driver, or a reference to the ConfigureInterface maintained by the Driver. A reference to the Driver provides access to the active ConfigureInterface. Thus, these ConfigurableToolsInterface classes may define and even require certain configuration information be made available via the instantiated ConfigureInterface object.


Engine Interface

An instance of an engine interface will allow the Driver simple access to the services of the engine. Each unique engine Interface will be instanced with the Class specified in the SAFS_ENGINE section of the ConfigureInterface. The instanced engine will gain access to the ConfigureInterface and proceed with initialization during the call to its ConfigurableToolsInterface launchInterface routine. Thus, each engine can independently specify required and optional configuration parameters the user needs to fulfill in the Configure source.