Thanks for giving SeleniumPlus a try!
Select any of the links above ("Project Assets", "Sample Project" etc.) to go directly to an area of interest.
We welcome any feedback (both good and bad) that can help us make the test automation experience better!
When meeting any problem, please
The SAFS/SeleniumPlus Development Team
SeleniumPlus Projects, like the SAMPLE project, are intended to be portable for other users and machines with SeleniumPlus installed. The entire Project should be saved--whether to CVS, GIT, or some othe storage medium. Although the "bin" subdirectory for the Project is generally not stored since these are compiled assets.
For example, to Import a Project that has been copied or saved to the local file system:
Note: Eclipse will NOT let you have/import two projects with the same name.
Importing older SeleniumPlus projects may require you to "fix" some of the paths in that Project's Java Build Path configuration and in each test configuration INI file (Test.INI) used for testing.
Newer SeleniumPlus projects have been created with the information that follows so they are already portable to different machines. For these newer projects you should not have to "fix" anything.
The latest versions of SeleniumPlus now support 2 features to maximize (or fix) Project portability:
For more detailed information on each:
The setting can be found in the Eclipse main menu under:
New Projects created with the latest PlugIn will now automatically use this SELENIUMPLUS_HOME Classpath Variable for the Project's Java Build Paths. You can see the Project's Java Build Paths by:
Currently, you should see settings using SELENIUMPLUS_HOME like:
SELENIUMPLUS_HOME/libs/JSTAFEmbedded.jar
SELENIUMPLUS_HOME/libs/selenium-server-standalone-2.44.0.jar
SELENIUMPLUS_HOME/libs/seleniumplus.jar
To fix such a portability issue, you can replace the explicit hardcoded library paths with new ones referencing and extending the SELENIUMPLUS_HOME Classpath Variable. You can do this by:
NOTE: This setting will only work on SAFS or SeleniumPlus with installed or updated JARs dating Nov 18, 2014 or later.
The JAR files in question are:
SAFS: | /lib/safsselenium.jar |
SeleniumPlus: | /libs/seleniumplus.jar |
The portability setting can be found in the Test.INI as:
To fix such a portability issue, you can replace the explicit hardcoded DriverRoot path in the Test.INI with the same setting as shown above.
Right click on Maps folder of the project, click "Selenium+->Create Map" to create new App Map file.
A new App Map will be created with .map extension. User can create multiple map files to separate language-specific component recognition strings and/or test configuration data.
Examples:
In general, there is a "primary" ProjectApp.map file which holds the bulk of all recognition strings and Application Constants. Then, there can be one or more App Map files containing language-specific values used by or overriding the primary App Map values.
The AppMap.order file is a means to chain multiple App Maps to be loaded in a specific order.
Example:
; ; Order App Maps Last In First Out (LIFO) for "chaining" ; App.map App_fr.map
Normally, an App Map contains multiple "sections". One of these is [ApplicationConstants] and the remaining user-defined sections are used to define "windows" or "containers" of components.
ApplicationConstants stores all test constants and data.
; ; Constants and other data. ; [ApplicationConstants] nlsSearch="Search" url="http://www.google.com" username="anonymous" password="newpassword"
Window or Container sections hold recognition strings used to identify child components within those containers.
In a container section, the item with the same name as the container is optional.
Example:
Google="id=viewport" is optional,
See the [Login] section? There is no "Login" item in that section. The default will be assumed (See the Note below.)
; ; Component recognition: ; ; Google main page window/component recognition ; [Google] Google="id=viewport" Apps="title=Apps" Search="text={^nlsSearch}" ; ; Google's Login window/component recognition ; [Login] UserName="name=Email" Password="name=Passwd" SignIn="id=signIn"
Note:
The item with the same name as the container (ex. "Google" and "Login"), if present, MUST contain a recognition string that *will* find the parent container of the contained children. When searching for a child, the parent is sought first.
If the parent is not found, then the search for the child will NOT occur.
If the item with the same name as the container is NOT provided, the default container to search is assumed to be the topmost document of the webpage, or the topmost document in any frame or iframe that was last searched.
FRAMEID=my_content_frame_id FRAMENAME=my_content_frame_name FRAMEXPATH=//iframe[@id='frameId'] FRAMEINDEX=N (1=first frame) RS by Index is not recommended. (note: parent/child hierarchy is separated by ";\;" ) (note: If there is no frame-expression in a RS, the last visited frame will be searched to find child components. By default, the last viisited frame is the main frame. And that is why if we specify a frame container, the children do not need to specify the parent frame in their RS. For example:[HelpPopup] HelpPopup="FRAMEID=VisualAnalyticsHubLogon_iframe" BtnHelpCenter="id=__item23"BtnHelpCenter is expected to be found in frame 'VisualAnalyticsHubLogon_iframe')
For child components, use supported type, property and attribute qualifiers, as necessary:
:PASM: (Property Attribute Search Mode -- Must be first, if present. See Notes.) TYPE="DOJO"|"SAP"; (See Notes.) ID=id; CLASS=class; NAME=name; TEXT=text; TITLE=title; LINK=linkInfo; PARTIALLINK=partialLinkInfo; TAG=tagname; INDEX=n; (1-based, NOT used alone, indicates the Nth matching item.) ITEMINDEX=n; (1-based, NOT used alone, indicates the Nth matching list item.) PATH=parent->child->grandchild; (NOT used alone. Path to a subitem in a List, ComboBox, Menu, Tree) PROPERTY=propname:propvalue; (can be used with others to provide more uniqueness) PROPERTYCONTAINS=propname:partialValue; (can be used with others to provide more uniqueness) Notes: Multiple qualifiers should be separated by semi-colons (";"). TYPE= is experimental and only supports "DOJO" and "SAP" at this time. Do not use. :PASM: if used, means everything that follows is explicitly property=value pairs. No PASM: Example 1:MyObject="Text=Some Text;enabled=true;ItemIndex=2;""TEXT" and "ITEMINDEX" are known qualifiers--not property names, while "enabled"--which is NOT a known qualifier--will be treated as a native object property/attribute to match. PASM: Example 2:
MyObject=":PASM:text=Some Text;enabled=true;itemindex=2;"With ":PASM:" leading; "text", "enabled", and "itemindex" are all sought as native object property/attribute values that must be matched.
Identify child elements by multiple native properties or attributes:
MyObject="aproperty=xxx;someattribute=yyy;anotherone=zzz"You don't need :PASM: if none of the properties or attributes have the same names as our qualifiers above.
Identify child objects using explicit XPATH or CSS RS:
MyObject="XPATH=.//div[contains(text(),'foo')]" MyObject="CSS=div:contains('foo')"
Generally, the 3 major browsers seem to support the same or similar mechanism for inspecting web page elements.
FireFox:
Chrome:
IExplore:
A Primary App Map hypothetically for Google (App.map):
; ; Constants and other data. ; [ApplicationConstants] nlsSearch="Search" ; ; Main Google window/component recognition ; [Google] Google="id=viewport" Apps="title=Apps" Search="text={^nlsSearch}" ; ; Google's Login window/compoent recognition ; [Login] Login="id=viewport" UserName="name=Email" Password="name=Passwd" SignIn="id=signIn"
A French App Map to override the "Search" text in the Primary App Map (App_fr.map):
; ; Constants and other data. ; [ApplicationConstants] nlsSearch="Recherche"
There is a SeleniumPlus ProcessContainer tool that can be used to interactively capture, modify, and test recognition strings natively using the SAFS/Selenium engine with the Selenium WebDriver. This can be used instead of--or in addition to--the Browser Tools mentioned above.
Review the SeleniumPlus ProcessContainer doc for more complete usage notes.
In particular, note that Selenium and SeleniumPlus only seek components ("Find Element") in the currently identified Frame or iFrame, if frames exist. If you get "No Such Element" or "...not found." for a particular Recognition: string you believe is good, it may be we are looking in the wrong Frame.
So, when attempting "Find Element" with ProcessContainer, you must do one of the following:
Example:
Recognition: XPATH=.//*[@id='aChildComponent_id']
or
Example:
Recognition: FRAMEID=myApps_iframe;\;XPATH=.//*[@id='aChildComponent_id']
Test Design Guidelines
App Map Format Info
Historic App Map Info
Specific "Categories" and "Qualifiers" in the above docs may not (yet) be supported by SeleniumPlus.
A fundamental overview of SAFS Expression Processing.
Historically, expression processing happens on every "field" for every action or command in a SAFS "inputrecord". The JSAFS Java code that SeleniumPlus is based upon retained that functionality.
Expression processing is "ON" by default.
That is, for any String argument or parameter passed to a SeleniumPlus class "action" or "command" there will be an attempt to process that String argument for possible expressions. (Note, that calls to other libaries that are NOT in the SeleniumPlus class--like WDLibrary, SearchObject, or WebDriver--do NOT have arguments processed for expressions.)
Operators that trigger String changes in action/command arguments:
^ '(Caret) Variable Prefix = 'Assignment operator " 'A single Double-Quote mark & 'String concatenate operator + 'Addition operator - 'Subtraction operator * 'Multiplication operator / 'Division operator % 'Modulus/Remainder operator ( 'Open Group operator ) 'Close Group operator
We have found that most SeleniumPlus users DO NOT need or want Expression processing enabled for the majority of their "action" or "comand" calls. Until an easy "fix" is available that does not break tests for existing JSAFS and SeleniumPlus users there are two options for controlling this:
There is a (somewhat) convenient quote() method available in your TestCase or TestRun for doing this.
Example:
Because the (-) subtraction operator exists in the string we have to quote() it to avoid expression processing.
This should make enclosing these String arguments with quote() unnecessary.
Example:
Because Expressions are OFF, the (-) subtraction operator should not trigger expression processing and the argument should not need to be quoted.
; ; Constants and other data. ; [ApplicationConstants] GoogleURL="http://www.google.com"
(Note: Once you are familiar with the commands and subclasses, you don't have to type the "SeleniumPlus." prefix.
You can just type the command name or subclass name directly.)
Classes in your "current" project will automatically receive RuntimeDataAware-ness at Runtime (i.e. when the test is run.) These classes will receive required object instances at runtime for doing things like retrieving values out of the runtime App Maps.
You normally don't have to think or worry about this because it happens for you behind the scenes every time you run a test. If you only use classes in your current Project, and don't reference Maps or Utility classes from other SeleniumPlus projects, then you can stop reading this and explore other sections of the Intro.
However, if you DO reference "other" SeleniumPlus projects in your current project--like an external "helper" project--or other projects that have runtime functionality you want to share and NOT duplicate--then you do need to consider the following.
Classes in those "other" projects that are not the "current" project will NOT receive their normal RuntimeDataAware-ness at runtime. This can present a problem if your try to use another project's testcases, or if you try to use those other projects' Map classes:
String val = helper.Map.SomeConstant();
The call will work normally when that project is the "current" project, but it may not work correctly if it is the "other" project. You can verify this by reviewing the Debug Log after a run. The Debug Log will show which packages and classes were checked for automatic injection of RuntimeDataAware-ness. The classes in the "other" project will NOT be listed in the log.
To fix this runtime issue:
The above example tells SeleniumPlus to check all classes in:
Recompile and Run and the issues encountered in the "other" project(s) should be resolved.
You can review the Debug Log after the Run and you should see where injecting the RuntimeDataAware classes in the "other" project(s) was attempted.
example:
cd c:\SeleniumPlus\SAMPLE runAutomation.bat
Note: See runAutomation.bat file for how to override App Map variables and App Map order.
SAFS and SeleniumPlus normally log a significant amount of information into the test log. This normally includes generic info as well as pass and fail information for test records.
The test INI file can be configured to change the LOGLEVEL for information sent to the logs.
The valid values for LOGLEVEL are:
; ; Test Info ; [SAFS_TEST] ... LOGLEVEL="INFO" ...
Note that "Counters" are still counting all records--including PASS and FAIL counts regardless of how the log is being filtered. However, if the LOGLEVEL is set to WARN or ERROR then the traditional test count summary that normally appears in the log will NOT be logged since they are not WARNings or ERRORs. This is a good thing for those that don't like the summary. It is a bad thing for those that do.
In SeleniumPlus we have provded some new Logging commands that allow the tester/developer to change the LOGLEVEL dynamically at runtime:
If you have reduced the logging by setting the LOGLEVEL in the INI file, or by one of the SeleniumPlus.Logging functions, you can return it to "normal" by calling:
This will enable that end-of-log test summary to make it into the log.
Only failed Asserts appear in the log. However, just like all other tests, the PASS/FAIL information increments in the test record Counters--which can be queried--will print to the log if the LOGLEVEL is set to the default "INFO".
[SAFS_DRIVER] DriverRoot="c:\seleniumplus\extra\automation"
The modified SeleniumPlus Eclipse IDE with the SeleniumPlus PlugIn provides many convenience features and a simplified interface for novice programmers. This includes certain levels of Eclipse interface filtering or hiding that may not be desirable for developers already comfortable with the Eclipse IDE--or even some other Java development environments.
It is possible to develop SeleniumPlus tests without these conveniences in your existing Eclipse environment or other Java IDE.
For Internet Explorer the user should make sure "Protected Mode" and the Status Bar are disabled.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BFCACHE
.HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BFCACHE
.FEATURE_BFCACHE
subkey may or may not be present, and should be created if it is not present. Important: Inside this key, create a DWORD
value named iexplore.exe with the value of 0.
1 2
String profile = "myprofile"; StartWebBrowser(URL, ID, SelectBrowser.BROWSER_NAME_FIREFOX, "30", "true", SelectBrowser.KEY_FIREFOX_PROFILE, profile);
1 2
String datapool = "c:\\chrome_custom_data"; StartWebBrowser(URL, ID, SelectBrowser.BROWSER_NAME_CHROME, "30", "true", quote(SelectBrowser.KEY_CHROME_USER_DATA_DIR), datapool);
1 2 3
String datapool = "c:\\chrome_custom_data"; String user = "Default"; StartWebBrowser(URL, ID, SelectBrowser.BROWSER_NAME_CHROME, "30", "true", quote(SelectBrowser.KEY_CHROME_USER_DATA_DIR), datapool, quote(SelectBrowser.KEY_CHROME_PROFILE_DIR), user);
1 2 3
String datapool = "c:\\chrome_custom_data"; String user = "Profile 1"; StartWebBrowser(URL, ID, SelectBrowser.BROWSER_NAME_CHROME, "30", "true", quote(SelectBrowser.KEY_CHROME_USER_DATA_DIR), datapool, quote(SelectBrowser.KEY_CHROME_PROFILE_DIR), user);
{ #The line begins with # is considered as comment #The preference is given as key:value, there are 3 kinds of value: string, boolean and integer. #The string value is quoted with double-quote, while boolean and integer are not quoted. "intl.accept_languages":"zh-cn", "accessibility.accesskeycausesactivation":false, "browser.download.folderList":2 }
1 2
String preferenceDataFile = "c:\\Pref.json.dat"; StartWebBrowser(URL, ID, SelectBrowser.BROWSER_NAME_FIREFOX, "30", "true", SelectBrowser.KEY_FIREFOX_PROFILE_PREFERENCE, preferenceDataFile);
{ #The line begins with # is considered as comment #Define command-line-options as key:value "lang":"en", #If the command-line-options doesn't need a value, then provide an empty value as key:"" "start-maximized":"", #"disable-smooth-scrolling":"", #Define preferences as value of key "seplus.chrome.preference.json.key" "seplus.chrome.preference.json.key": { #The preferences are given as key:value "intl.accept_languages" :"zh-CN-pseudo", "intl.charset_default" :"utf-8" } }
1 2
String preferenceDataFile = "c:\\Pref.json.dat"; StartWebBrowser(URL, ID, SelectBrowser.BROWSER_NAME_CHROME, "30", "true", quote(SelectBrowser.KEY_CHROME_PREFERENCE), preferenceDataFile);
SeleniumPlus Class JavaDoc
Selenium WebDriver API
SAFS Keywords Reference
SAFS Homepage on SourceForge
SAFS Test Design Guidelines
SAFS Image-Based Testing
"Update" expects that "SeleniumPlus" has already successfully installed, so the system environment %SELENUM_PLUS% has been defined correctly.
Update SelenumPlus jars and SeleniumPlus eclipse plugin to the latest level. During the update, %SELENUM_PLUS%/update_bak and %SELENIUM_PLUS%/eclipse/plugins/update_bak are created so user can revert the changes back.
There are 3 ways:
For Update SeleniumPlus, following are the steps.
This script should be in folder %SELENIUM_PLUS%\extra or %SAFSDIR%\extra.
In the script, we are using the internal update resource which is faster. If you prefer using external update resource, then comment "internal resource" and un-comment "external resource".
REM External update resource REM SET SE_LIB_UPDATE=https://github.com/SAFSDEV/UpdateSite/releases/download/seleniumplus/SEPLUS.LIB.UPDATE.ZIP REM SET SE_PLUGIN_UPDATE=https://github.com/SAFSDEV/UpdateSite/releases/download/seleniumplus/SEPLUS.PLUGIN.UPDATE.ZIP REM SET SAFS_LIB_UPDATE=https://github.com/SAFSDEV/UpdateSite/releases/download/safs/SAFS.LIB.UPDATE.ZIP REM Internal update resource SET SE_LIB_UPDATE=http://safsbuild:81/jenkins/job/SeleniumPlus/ws/updatesite/lib/latest/SEPLUS.LIB.UPDATE.ZIP SET SE_PLUGIN_UPDATE=http://safsbuild:81/jenkins/job/SeleniumPlus/ws/updatesite/plugin/latest/SEPLUS.PLUGIN.UPDATE.ZIP SET SAFS_LIB_UPDATE=http://safsbuild:81/jenkins/job/SAFS/ws/updatesite/lib/latest/SAFS.LIB.UPDATE.ZIP
If automated update fails then use manual steps to update SeleniumPlus environment.
SeleniumPlus library update:
SeleniumPlus eclipse plugin update:
SeleniumPlus is packaged and delivered for a small-footprint, fast execution environment when compared to a full SAFS install. It has been optimized to provide targetted test automation support for HTML applications using Selenium WebDriver. The traditional capability to interface to other test automation tools capable of testing other technologies is intentionally removed from the SeleniumPlus install.
However, individual SeleniumPlus Projects can be configured to take advantage of SAFS and other testing tools if a full SAFS installation exists on the runtime machine. For example, if you have a hybrid application that needs both HTML *and* Flex support then you might wish to enable SAFS within the project used to test that application.
[STAF]
NOSTAF=FALSE
[SAFS_DRIVER]
DriverRoot="%SAFSDIR%"
Note how the setting uses the SAFSDIR Environment variable that MUST exist at runtime.
Your test execution won't look any different, and you should get the exact same results.
By reviewing the running processes in Task Manager you would find 2 additional processes at runtime:
Other tools, scripting languages, Command(CMD) prompts, and COM-enabled applications or languages can now:
With SAFS enabled, you can now add automation support provided by other SAFS engines like:
At this time, the most recommended alternative SAFS Engine would be the SmartBear TestComplete engine. It has received the most development support in recent years along with the SAFS/Selenium Engine.
In order to use an alternative SAFS Engine, the underlying tool--like SmartBear's TestComplete--must be properly installed on the runtime system. Consult the SAFS Install/Release Notes for information concerning configuring the particular tool for SAFS integration.
Then, we simply enable the use of the engine in the TEST.INI configuration file. The SAFS/SeleniumPlus execution runtime will automatically handle the launching and shutdown of the tool during testing.
Below is an example of enabling the SmartBear TestComplete engine in the Project's TEST.INI configuration file:
[SAFS_ENGINES]
First=org.safs.tools.engines.SAFSTC
[SAFS_TC]
AUTOLAUNCH=TRUE
HOOK="%SAFSDIR%\TCAFS\TCAFS.vbs"
ConvertSAFSInputKeysSyntax=TRUE
ConvertSAFSItemPathSyntax=TRUE
And that's it. The next time a test is run the newly configured Engine will be part of the available toolset. If the tool launches any startup window or Monitor of its own you will likely see it during the course of test execution.
Note that different tools will likely require different component recognition string syntax in the App Map. So, for example, an HTML XPATH recognition string that works for Selenium WebDriver will not work for SmartBear TestComplete. You will need to consult the information available for the chosen Engine to know how to acquire and specify App Map entries for that specific Engine.
Here are the critical settings in a test.ini:
# Settings for a remote Selenium Server # SELENIUMHOST and SELENIUMPORT are used to connect Selenium Server (standalone or hub) SELENIUMHOST=remote.server.name SELENIUMPORT=4444 (setting not required if default) # 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
# Selenium standalone server should run on local machine at default port 4444 # [SAFS_SELENIUM] # If nothing is specified. # Selenium standalone server should run on local machine at port 6666 [SAFS_SELENIUM] SeleniumPort=6666 # Selenium standalone server should run on machine D99999.yourCompany.com at port 4444 # test actions will actually happen in the browser opened on machine D99999.yourCompany.com [SAFS_SELENIUM] SeleniumHost=D99999.yourCompany.com SeleniumPort=4444 # Selenium hub should run on machine selenium.hub.machine at port 5555 # Selenium node should run on machine node.yourCompany.com at port 6666 and connecting to hub server # test actions will actually happen in the browser opened on machine node.yourCompany.com [SAFS_SELENIUM] SeleniumHost=selenium.hub.machine SeleniumPort=5555 SELENIUMNODE=node.yourCompany.com:6666 # Selenium hub should run on local machine at port 5555 # Selenium node should run on machine node.yourCompany.com at port 6666 and connecting to hub server # test actions will actually happen in the browser opened on machine node.yourCompany.com [SAFS_SELENIUM] SeleniumPort=5555 SELENIUMNODE=node.yourCompany.com:6666
[SAFS_SELENIUM]
# WEB_DRIVERS is used to set the specific browser
# drivers (separated by colon :) to start with selenium server.
# The following setting means 3 drivers, IE, chrome and edge will
# start with the selenium server.
WEB_DRIVERS=explorer:chrome:MicrosoftEdge
VM parameter 'safs.selenium.web.drivers' is used to
set the specific browser drivers (separated by colon :) to start with selenium server.
The following setting means 2 drivers, IE and edge will start with the selenium server,
and in the class SampleTest, the user can test with the chrome or edge browser.
java -Dsafs.selenium.web.drivers=chrome:MicrosoftEdge SampleTest
SET CLASSPATH= <pathTo>\seleniumplus.jar; <pathTo>\JSTAFEmbedded.jar; <pathTo>\selenium-server-standalone-<version>.jar SET JAVA_EXE=<pathTo>\java.exe (JRE Java 7 minimum) %JAVA_EXE% -Xms512m -Xmx1g -Djava.rmi.server.hostname=machine.intranet.com -Dwebdriver.chrome.driver=<pathTo>\chromedriver.exe -Dwebdriver.ie.driver=<pathTo>\IEDriverServer.exe -cp %CLASSPATH% org.safs.selenium.util.SeleniumServerRunner -jar <pathTo>\selenium-server-standalone-<version>.jar -timeout=20 -browserTimeout=60 -safs.rmi.server
In order for a remote Selenium Server to provide equivalent augmented support provided by SeleniumPlus, the remote Selenium Server must be launched in a manner that allows us to inject that support into the remote Java JVM running the Selenium Server. Consult Using Selenium Server Runner to know how.
Selenium hub Server.
The first line tells us that a selenium hub server is being started.
Selenium node Server with injected RMI server into the Selenium Server JVM.
The first 3 lines of the output tell us that RMI-server has been injected into the Selenium Server JVM;
while the 4th line tells us that a selenium node server is being started;
and the last 2th line tells us that the node has registered on hub server.
During the test, sometimes users need to manipulate the object within the browser directly, which can be
achieved by Javascript. This section explains how to execute Javascript through SeleniumPlus.
There are something we should understand. Such as the parameters of these APIs and how these Java-parameters are passed to Javascript as parameters, it is important! We don't need to understand all of them :) , the items below are listed by necessity priority:
try{
//do some javascript actions
}catch(err){
throw_error(err);
}
WebElement webelement = null;//User must assign it with a valid value. String event = "mousedown"; int timeout = 1000;//milliseconds DefaultJSEventListener listener = new DefaultJSEventListener(event); //add listener for event String listenerID = WDLibrary.addJavaScriptEventListener(webelement, event, listener); //do some mousedown related work, for example 'click' webelement.click(); //wait for event happen if(listener.waitEventFired(timeout)){ //ok, event has been fired.} //remove the listener WDLibrary.removeJavaScriptEventListener(webelement, event, listenerID);
There are something we should understand. Such as the parameters of these APIs and how these Java-parameters are passed to Javascript as parameters, it is important! We don't need to understand all of them :) , the items below are listed by necessity priority:
//set "your text" to innerHTML of Component Map.Google.SignIn WebElement we = SeleniumPlus.getObject(Map.Google.SignIn); String script = "arguments[0].innerHTML=arguments[1];"; List<Object> params = new ArrayList<Object>(); params.add(we);//arguments[0] params.add("your text");//arguments[1] SeleniumPlus.executeScript(script, params.toArray(new Object[0]));
//get innerHTML of component Map.Google.SignIn script = "return arguments[0].innerHTML;"; params.clear(); params.add(we);//arguments[0] Object result = SeleniumPlus.executeScript(script, params.toArray(new Object[0]));
//Example #1: Performing a sleep in the browser under test.
long start = System.currentTimeMillis();
String script = "var callback = arguments[arguments.length - 1];"+
"window.setTimeout(callback, 500);";
SeleniumPlus.executeAsyncScript(script);
System.out.println("Elapsed time: " + System.currentTimeMillis() - start);
//Example #2, call REST service to get a result.
try{
WDTimeOut.setScriptTimeout(1, TimeUnit.SECONDS);
JavaScriptFunctions.DEBUG_OUTPUT_JAVASCRIPT_FUNCTIONS = true;
JavaScriptFunctions.setJsDebugLogEnable(true);
String script = "try{ "
+ " var callback = arguments[arguments.length - 1];"
+ " debug('try to get registration service.');"
+ " var service = registry.getRegistrationService();"
+ " if(service==undefined){"
+ " debug('Failed to get service');"
+ " }else{"
+ " debug('we got registration service.'); "
+ " }"
+ " service.get({'user-id': 'administrator'}).done(callback).fail(callback);"
+ "}catch(error){"
+ " debug('we met exception');"
+ " throw_error(error);"
+ "}";
Object results = SeleniumPlus.executeAsyncScript(script);
System.out.println(results);
}catch(Exception e){
System.out.println(e.getMessage());
}finally{
WDTimeOut.resetScriptTimeout(0, TimeUnit.MILLISECONDS);
}
//Example #3: Injecting a XMLHttpRequest and waiting for the result: String script = "var callback = arguments[arguments.length - 1];" + "var xhr = new XMLHttpRequest();" + "xhr.open('GET', '/resource/data.json', true);" + "xhr.onreadystatechange = function() {" + " if (xhr.readyState == 4) {" + " callback(xhr.responseText);" + " }" + "};" + "xhr.send();"; //Wait result for at the most 5 seconds WDTimeOut.setScriptTimeout(5, TimeUnit.SECONDS); Object result = SeleniumPlus.executeAsyncScript(script); JsonObject json = new JsonParser().parse((String) result);
//Example #4: Synchronizing a test with an AJAX application:
Click(Map.Mail.ComposeButton);
String script = "var callback = arguments[arguments.length - 1];" +
"mailClient.getComposeWindowWidget().onload(callback);";
Object result = SeleniumPlus.executeAsyncScript(script);
Component.InputCharacters(Map.Mail.To, "bog@example.com");
SeleniumPlus.ExecuteScript( Map.Google.SignIn, // The WebElement passed as 'arguments[0]' to the script. "arguments[0].innerHTML=arguments[1];", // Script to set the WebElements innerHTML value. "my text value"); // The value passed as 'arguments[1]' to set to innerHTML.
SeleniumPlus.ExecuteScript( Map.Google.SignIn, // The WebElement passed as 'arguments[0]' to the script. "return arguments[0].innerHTML;"); // A script to return the WebElemenbts innerHTML. //scriptResult should get the innerHTML value returned. String scriptResult = SeleniumPlus.prevResults.getStatusInfo();
There are some tools can record "selenium test" and store it into a file.
Selenium Builder will store it in JSON format.
Selenium IDE can store it in HTML format.
This kind of file contains the "selenium test" and we call these files as "Selenium Scripts".
This section explains how to execute "Selenium Scripts" through SeleniumPlus API CallScript.
The HTML script is stored as a Table.
the tag <tbody> means the begin of the test.
the tag </tbody> means the end of the test.
the tag <tr> means the begin of one step.
the tag </tr> means the end of one step.
each test step can contain multiple <td></td>, they are used to hole the comand and parameters.
Below is an example snippet, which is part of the real
sebuild script in
regression test.
<tbody> <tr> <td>open</td> <td>${baseurl}</td> <td>${FormsBrowser}</td> </tr> <tr> <td>pause</td> <td>2000</td> <td> </td> </tr> <tr> <td>captureEntirePageScreenshot</td> <td>Actuals/FormsSRTest/formsSRTest-1.png</td> <td></td> </tr> <tr> <td>click</td> <td>${Map:FormsMain:CheckBox2}</td> <td></td> </tr> <tr> <td>close</td> <td>${FormsBrowser}</td> <td> </td> </tr> </tbody>[go back]
In some testing environment, Internet access is not direct, but through a Proxy server.
This section is talking about HTTP proxy settings in SeleniumPlus.
There are 2 ways:
[SAFS_SELENIUM] ;define the HTTP PROXY host name to connect Internet GATEWAYHOST=yourGateway.net ;define the HTTP PROXY port number to connect Internet GATEWAYPORT=80 ;define the HTTP PROXY "bypass address" when connecting INTRANET PROXY_BYPASS_ADDRESS=localhost,127.0.0.1,host.not.thru.gateway[go back]
The HTTP proxy can also be set by the optional parameters of StartWebBrowser API. The optional parameters are given as pair (key, value). The keys related to "HTTP proxy" are:
//Start the firefox web browser with proxy server as "proxy.server" and proxy server port as "8080" StartWebBrowser("http://www.google.com", "GoogleMain", new String[]{ SelectBrowser.BROWSER_NAME_FIREFOX, "10", "true", quote(SelectBrowser.KEY_PROXY_SETTING), quote("proxy.server:8080") }); //Start the firefox web browser with proxy server as "proxy.server" and proxy server port as "8080" //local.site1, local.site2 will not be routed through "proxy.server" StartWebBrowser("http://www.google.com", "GoogleMain", new String[]{ SelectBrowser.BROWSER_NAME_FIREFOX, "10", "true", quote(SelectBrowser.KEY_PROXY_SETTING), quote("proxy.server:8080"), quote(SelectBrowser.KEY_PROXY_BYPASS_ADDRESS), quote("local.site1, local.site2") });