IDEMPIERE-92 - Integrate Selenium. Refactor to 3 project, webdriver+jq, selenese and ztl. Refactor the webdriver+jq code to make it easier to write new test cases. Added logout and change role test case to the webdriver+jq project. Use GardenAdmin instead of SuperUser for example test cases.

This commit is contained in:
Heng Sin Low 2012-12-11 01:20:08 +08:00
parent 6afdbc8a9b
commit 9d25015ddf
25 changed files with 508 additions and 232 deletions

View File

@ -2,19 +2,6 @@
<classpath> <classpath>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="lib/selenium-java-2.25.0.jar" sourcepath="lib/selenium-java-srcs.jar"/> <classpathentry kind="lib" path="lib/selenium-server-standalone-2.27.0.jar" sourcepath="lib/selenium-server-2.27.0-srcs.jar"/>
<classpathentry kind="lib" path="lib/junit-4.8.2.jar"/>
<classpathentry kind="lib" path="lib/selenium-firefox-driver-2.25.0.jar"/>
<classpathentry kind="lib" path="lib/selenium-api-2.25.0.jar"/>
<classpathentry kind="lib" path="lib/selenium-support-2.25.0.jar"/>
<classpathentry kind="lib" path="lib/guava-12.0.1.jar"/>
<classpathentry kind="lib" path="lib/json-20080701.jar"/>
<classpathentry kind="lib" path="lib/commons-exec-1.1.jar"/>
<classpathentry kind="lib" path="lib/httpcore-4.1.2.jar"/>
<classpathentry kind="lib" path="lib/httpclient-4.1.2.jar"/>
<classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/>
<classpathentry kind="lib" path="lib/ztl/ztl-2.0.0-SNAPSHOT.jar" sourcepath="lib/ztl/ztl-2.0.0-sources.jar"/>
<classpathentry kind="lib" path="lib/selenium-remote-driver-2.25.0.jar"/>
<classpathentry kind="lib" path="lib/ztl/selenium-server-standalone-2.25.0.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

View File

@ -1,28 +1,10 @@
config.properties test
- configuration file for running Ztl generator and Ztl test
ZtlGenerator.launch
- Eclipse launch configuration for Ztl generator
zk.jq.test
- Example test cases written using Selenium Web Driver and Zk JQ selector - Example test cases written using Selenium Web Driver and Zk JQ selector
zk.selenese.test
- Example test cases exported from Selenium IDE ( JUnit4 + WebDriver )
zk.ztl.test
- Example test cases generated by Ztl generator
resource/selenese
- selenese test script recorded by Selenium IDE
resource/ztl/zk/ztl/test
- ztl test script
Notes Notes
====== ======
* Mapping between selenese ( the native format created by Selenium IDE recording ) and * Use the AdempiereIDGenerator and your browser's inspect element tool to find out the selector for the element that you need to access. Alternatively,
web driver export is not one to one. For e.g, the fireEvent command is not needed in you can use the script created from Selenium IDE recording as a guide.
web driver test script.
* For execution of test cases, you don't need AdempiereIDGenerator if you only use zk id instead of uuid(html id)
* You must change the "target" instance variable value to "" in the generated ztl java source

View File

@ -5,28 +5,45 @@ import java.util.List;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.SearchContext; import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebElement;
/** /**
* utility class to find elements using zk jq selector * utility class to find elements using zk jq selector
* @author hengsin * @author hengsin
* *
*/ */
public class Zk extends By { public class Zk {
private Zk() {
}
public static By jq(String selector) {
return new ByJqSelector(selector);
}
public static class ByJqSelector extends By {
private String selector; private String selector;
private Zk(String selector) { private ByJqSelector(String selector) {
this.selector = selector; this.selector = selector;
} }
@Override @Override
public List<WebElement> findElements(SearchContext context) { public List<WebElement> findElements(SearchContext context) {
List<WebElement> list = (List<WebElement>) ((JavascriptExecutor)context).executeScript("return jq('" + selector + "').get();"); JavascriptExecutor executor = null;
String selector = this.selector;
if (context instanceof WebDriver) {
executor = (JavascriptExecutor) context;
} else {
RemoteWebElement element = (RemoteWebElement) context;
String id = element.getAttribute("id");
selector = "#"+id+" "+selector;
executor = (JavascriptExecutor) element.getWrappedDriver();
}
List<WebElement> list = (List<WebElement>) executor.executeScript("return jq('" + selector + "').get();");
return list; return list;
} }
public static Zk jq(String selector) {
return new Zk(selector);
} }
} }

View File

@ -0,0 +1,142 @@
package test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.util.concurrent.TimeUnit;
import org.idempiere.ui.zk.selenium.Zk;
import org.junit.After;
import org.junit.Before;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class AbstractTestCase {
protected WebDriver driver;
protected StringBuffer verificationErrors = new StringBuffer();
private String baseUrl;
@Before
public void setUp() throws Exception {
driver = new FirefoxDriver();
// driver = new ChromeDriver();
baseUrl = "http://localhost:8080/webui/";
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
}
protected void type(String locator, String value) {
WebElement element = driver.findElement(Zk.jq(locator));
element.clear();
element.sendKeys(value);
}
protected void select(String locator, String label) {
WebElement select = driver.findElement(Zk.jq(locator));
select(select, label);
}
protected void select(WebElement select, String label) {
select.findElement(Zk.jq(".z-combobox-btn")).click();
try {
Thread.sleep(500);
} catch (InterruptedException e) {}
select.findElement(Zk.jq("$"+escape(label))).click();
}
protected void clickCheckbox(String locator) {
driver.findElement(Zk.jq("$"+locator+" ~ input")).click();
}
protected void clickButton(String locator) {
driver.findElement(Zk.jq(locator)).click();
}
protected void login() throws Exception {
driver.get(baseUrl);
Thread.sleep(500);
// enter user name
type("$loginPanel $txtUserId", "GardenAdmin");
// enter password
type("$loginPanel $txtPassword", "GardenAdmin");
//select language
select("$loginPanel $lstLanguage", "English");
// check select role
clickCheckbox("$loginPanel $chkSelectRole");
// click ok button
clickButton("$loginPanel $Ok");
selectRole("GardenWorld", "GardenWorld Admin", "HQ");
// wait for home page
WebElement loginUserElement = waitForElement("$loginUserAndRole");
// assert login user and role
assertEquals("GardenAdmin@GardenWorld.HQ/GardenWorld Admin", loginUserElement.getText());
}
protected WebElement waitForElement(String locator) throws InterruptedException {
By loginUserQuery = Zk.jq(locator);
for (int second = 0;; second++) {
if (second >= 60)
fail("timeout");
try {
if (isElementPresent(loginUserQuery))
break;
} catch (Exception e) {
}
Thread.sleep(1000);
}
return driver.findElement(loginUserQuery);
}
protected void selectRole(String client, String role, String org) throws InterruptedException {
// wait for role panel
WebElement lstClient = waitForElement("$rolePanel $lstClient");
// select client
if (lstClient != null && lstClient.isDisplayed()) {
select(lstClient, client);
}
// select role
select("$rolePanel $lstRole", role);
// select organization
select("$rolePanel $lstOrganisation", org);
// click ok button
clickButton("$rolePanel $Ok");
}
protected boolean isElementPresent(By by) {
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
}
}
@After
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
}
}
protected String escape(String role) {
return role.replace(" ", "\\\\ ");
}
}

View File

@ -0,0 +1,30 @@
package test;
import org.idempiere.ui.zk.selenium.Zk;
import org.junit.Test;
import org.openqa.selenium.WebElement;
import static org.junit.Assert.*;
public class ChangeRoleTest extends AbstractTestCase {
@Test
public void testLogin() throws Exception {
login();
Thread.sleep(2000);
driver.findElement(Zk.jq("$changeRole")).click();
Thread.sleep(1000);
// wait for home page
selectRole("GardenWorld", "GardenWorld User", "HQ");
WebElement element = waitForElement("$loginUserAndRole");
// assert login user and role
assertEquals("GardenAdmin@GardenWorld.HQ/GardenWorld User", element.getText());
}
}

View File

@ -0,0 +1,15 @@
package test;
import org.junit.*;
/**
* Web Driver + zk jq selector, doesn't required AdempiereIdGenerator
* @author hengsin
*
*/
public class LoginTest extends AbstractTestCase {
@Test
public void testLogin() throws Exception {
login();
}
}

View File

@ -0,0 +1,21 @@
package test;
import org.idempiere.ui.zk.selenium.Zk;
import org.junit.Test;
import org.openqa.selenium.WebElement;
import static org.junit.Assert.*;
public class LogoutTest extends AbstractTestCase {
@Test
public void testLogin() throws Exception {
login();
WebElement logout = driver.findElement(Zk.jq("$logout"));
logout.click();
Thread.sleep(2000);
WebElement loginWindow = driver.findElement(Zk.jq("$loginPanel"));
assertTrue(loginWindow != null && loginWindow.isDisplayed());
}
}

View File

@ -1,94 +0,0 @@
package zk.jq.test;
import java.util.concurrent.TimeUnit;
import org.idempiere.ui.zk.selenium.Zk;
import org.junit.*;
import static org.junit.Assert.*;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
/**
* Web Driver + zk jq selector, doesn't required AdempiereIdGenerator
* @author hengsin
*
*/
public class LoginTest {
private WebDriver driver;
private String baseUrl;
private StringBuffer verificationErrors = new StringBuffer();
@Before
public void setUp() throws Exception {
driver = new FirefoxDriver();
baseUrl = "http://127.0.0.1:8080/";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
@Test
public void testLogin() throws Exception {
// open | /webui/ |
driver.get(baseUrl + "/webui/");
// enter user name
driver.findElement(Zk.jq("$loginPanel $txtUserId")).clear();
driver.findElement(Zk.jq("$loginPanel $txtUserId")).sendKeys("SuperUser");
// enter password
driver.findElement(Zk.jq("$loginPanel $txtPassword")).clear();
driver.findElement(Zk.jq("$loginPanel $txtPassword")).sendKeys("System");
// check select role
driver.findElement(Zk.jq("$loginPanel $chkSelectRole ~ input")).click();
// click ok button
driver.findElement(Zk.jq("$loginPanel $Ok")).click();
// wait for role panel
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (isElementPresent(Zk.jq("$rolePanel $lstClient"))) break; } catch (Exception e) {}
Thread.sleep(1000);
}
// select GardenWorld client
driver.findElement(Zk.jq("$rolePanel $lstClient ~ .z-combobox-btn")).click();
driver.findElement(Zk.jq("$rolePanel $lstClient $GardenWorld")).click();
// select GardenWorld admin role
driver.findElement(Zk.jq("$rolePanel $lstRole ~ .z-combobox-btn")).click();
//note the 4 \\\\ needed to escape the space character. ugly but it works
driver.findElement(Zk.jq("$rolePanel $lstRole $GardenWorld\\\\ Admin")).click();
// select HQ organization
driver.findElement(Zk.jq("$rolePanel $lstOrganisation ~ .z-combobox-btn")).click();
driver.findElement(Zk.jq("$rolePanel $lstOrganisation $HQ")).click();
// click ok button
driver.findElement(Zk.jq("$rolePanel $Ok")).click();
// wait for home page
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (isElementPresent(Zk.jq("$loginUserAndRole"))) break; } catch (Exception e) {}
Thread.sleep(1000);
}
// assert login user and role
assertEquals("SuperUser@GardenWorld.HQ/GardenWorld Admin", driver.findElement(Zk.jq("$loginUserAndRole")).getText());
}
@After
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
}
}
private boolean isElementPresent(By by) {
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
}
}
}

7
selenese/.classpath Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="/idempiere.zk.selenium/lib/selenium-server-standalone-2.27.0.jar" sourcepath="/idempiere.zk.selenium/lib/selenium-server-2.27.0-srcs.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

17
selenese/.project Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>selenese</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

20
selenese/Readme.txt Normal file
View File

@ -0,0 +1,20 @@
test
- Example test cases exported from Selenium IDE ( JUnit4 + WebDriver )
resource/selenese
- selenese test script recorded by Selenium IDE
Notes
======
* The mapping between selenese ( the native format created from Selenium IDE recording ) and
web driver export is not one to one. For e.g, the fireEvent command is not needed in
web driver test script.
* While both "id=loginPanel_Ok" and "loginPanel_Ok" work the same when you execute selenese test with Selenium IDE,
you must use the id= syntax for the web driver export to work.
* The selenese script recorded by Selenium IDE required changes ( most of the time, you need to add insert fireEvent and sleep command )
before you can run it with Selenium IDE. However, it mostly work if you export it to the Java WebDriver format and run it from Eclipse.
* AdempiereIDGenerator is required for the recording and execution of selenese test cases.

View File

@ -18,47 +18,32 @@
</tr> </tr>
<tr> <tr>
<td>type</td> <td>type</td>
<td>id=loginPanel_grdLogin_rowUser_txtUserId</td> <td>id=loginPanel_txtUserId</td>
<td>SuperUser</td> <td>GardenAdmin</td>
</tr> </tr>
<tr> <tr>
<td>fireEvent</td> <td>fireEvent</td>
<td>id=loginPanel_grdLogin_rowUser_txtUserId</td> <td>id=loginPanel_txtUserId</td>
<td>blur</td> <td>blur</td>
</tr> </tr>
<tr> <tr>
<td>type</td> <td>type</td>
<td>id=loginPanel_grdLogin_rowPassword_txtPassword</td> <td>id=loginPanel_txtPassword</td>
<td>System</td> <td>GardenAdmin</td>
</tr> </tr>
<tr> <tr>
<td>fireEvent</td> <td>fireEvent</td>
<td>id=loginPanel_grdLogin_rowPassword_txtPassword</td> <td>id=loginPanel_txtPassword</td>
<td>blur</td> <td>blur</td>
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>id=loginPanel_grdLogin_rowSelectRole_chkSelectRole-real</td> <td>id=loginPanel_lstLanguage-btn</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>id=loginPanel_Ok</td> <td>css=#loginPanel_lstLanguage_English &gt; td.z-comboitem-text</td>
<td>10</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>id=rolePanel_grdChooseRole_rowclient_lstClient-btn</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>id=rolePanel_grdChooseRole_rowclient_lstClient-btn</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=#rolePanel_grdChooseRole_rowclient_lstClient_zk_GardenWorld &gt; td.z-comboitem-text</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
@ -68,12 +53,57 @@
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>id=rolePanel_grdChooseRole_rowOrganisation_lstOrganisation-btn</td> <td>id=loginPanel_chkSelectRole-real</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>css=#rolePanel_grdChooseRole_rowOrganisation_lstOrganisation_HQ &gt; td.z-comboitem-text</td> <td>id=loginPanel_Ok</td>
<td>10</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>id=rolePanel_lstClient-btn</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>id=rolePanel_lstClient-btn</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=#rolePanel_lstClient_GardenWorld &gt; td.z-comboitem-text</td>
<td></td>
</tr>
<tr>
<td>pause</td>
<td>1000</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>id=rolePanel_lstRole-btn</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=#rolePanel_lstRole_GardenWorld_Admin &gt; td.z-comboitem-text</td>
<td></td>
</tr>
<tr>
<td>pause</td>
<td>1000</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>id=rolePanel_lstOrganisation-btn</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=#rolePanel_lstOrganisation_HQ &gt; td.z-comboitem-text</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
@ -89,7 +119,7 @@
<tr> <tr>
<td>assertText</td> <td>assertText</td>
<td>id=loginUserAndRole</td> <td>id=loginUserAndRole</td>
<td>SuperUser@GardenWorld.HQ/GardenWorld Admin</td> <td>GardenAdmin@GardenWorld.HQ/GardenWorld Admin</td>
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
@ -98,17 +128,32 @@
</tr> </tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>id=rolePanel_grdChooseRole_rowclient_lstClient</td> <td>id=rolePanel_lstClient</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>id=rolePanel_grdChooseRole_rowclient_lstClient-btn</td> <td>id=rolePanel_lstRole-btn</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>css=#rolePanel_grdChooseRole_rowclient_lstClient_System_ &gt; td.z-comboitem-text</td> <td>css=#rolePanel_lstRole_GardenWorld_User &gt; td.z-comboitem-text</td>
<td></td>
</tr>
<tr>
<td>pause</td>
<td>1000</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>id=rolePanel_lstOrganisation-btn</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=#rolePanel_lstOrganisation_HQ &gt; td.z-comboitem-text</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
@ -124,7 +169,7 @@
<tr> <tr>
<td>assertText</td> <td>assertText</td>
<td>id=loginUserAndRole</td> <td>id=loginUserAndRole</td>
<td>SuperUser@System.*/System Administrator</td> <td>GardenAdmin@GardenWorld.HQ/GardenWorld User</td>
</tr> </tr>
</tbody></table> </tbody></table>
</body> </body>

View File

@ -18,27 +18,42 @@
</tr> </tr>
<tr> <tr>
<td>type</td> <td>type</td>
<td>id=loginPanel_grdLogin_rowUser_txtUserId</td> <td>id=loginPanel_txtUserId</td>
<td>SuperUser</td> <td>GardenAdmin</td>
</tr> </tr>
<tr> <tr>
<td>fireEvent</td> <td>fireEvent</td>
<td>id=loginPanel_grdLogin_rowUser_txtUserId</td> <td>id=loginPanel_txtUserId</td>
<td>blur</td> <td>blur</td>
</tr> </tr>
<tr> <tr>
<td>type</td> <td>type</td>
<td>id=loginPanel_grdLogin_rowPassword_txtPassword</td> <td>id=loginPanel_txtPassword</td>
<td>System</td> <td>GardenAdmin</td>
</tr> </tr>
<tr> <tr>
<td>fireEvent</td> <td>fireEvent</td>
<td>id=loginPanel_grdLogin_rowPassword_txtPassword</td> <td>id=loginPanel_txtPassword</td>
<td>blur</td> <td>blur</td>
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>id=loginPanel_grdLogin_rowSelectRole_chkSelectRole-real</td> <td>id=loginPanel_lstLanguage-btn</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=#loginPanel_lstLanguage_English &gt; td.z-comboitem-text</td>
<td></td>
</tr>
<tr>
<td>pause</td>
<td>1000</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>id=loginPanel_chkSelectRole-real</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
@ -48,17 +63,17 @@
</tr> </tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>id=rolePanel_grdChooseRole_rowclient_lstClient-btn</td> <td>id=rolePanel_lstClient-btn</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>id=rolePanel_grdChooseRole_rowclient_lstClient-btn</td> <td>id=rolePanel_lstClient-btn</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>css=#rolePanel_grdChooseRole_rowclient_lstClient_GardenWorld &gt; td.z-comboitem-text</td> <td>css=#rolePanel_lstClient_GardenWorld &gt; td.z-comboitem-text</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
@ -68,12 +83,12 @@
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>id=rolePanel_grdChooseRole_rowRole_lstRole-btn</td> <td>id=rolePanel_lstRole-btn</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>css=#rolePanel_grdChooseRole_rowRole_lstRole_GardenWorld_Admin &gt; td.z-comboitem-text</td> <td>css=#rolePanel_lstRole_GardenWorld_Admin &gt; td.z-comboitem-text</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
@ -83,12 +98,12 @@
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>id=rolePanel_grdChooseRole_rowOrganisation_lstOrganisation-btn</td> <td>id=rolePanel_lstOrganisation-btn</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>css=#rolePanel_grdChooseRole_rowOrganisation_lstOrganisation_HQ &gt; td.z-comboitem-text</td> <td>css=#rolePanel_lstOrganisation_HQ &gt; td.z-comboitem-text</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
@ -104,7 +119,7 @@
<tr> <tr>
<td>assertText</td> <td>assertText</td>
<td>id=loginUserAndRole</td> <td>id=loginUserAndRole</td>
<td>SuperUser@GardenWorld.HQ/GardenWorld Admin</td> <td>GardenAdmin@GardenWorld.HQ/GardenWorld Admin</td>
</tr> </tr>
</tbody></table> </tbody></table>
</body> </body>

View File

@ -1,4 +1,4 @@
package zk.selenese.test; package test;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.junit.*; import org.junit.*;
@ -19,49 +19,52 @@ public class LoginTest {
public void setUp() throws Exception { public void setUp() throws Exception {
driver = new FirefoxDriver(); driver = new FirefoxDriver();
baseUrl = "http://127.0.0.1:8080/"; baseUrl = "http://127.0.0.1:8080/";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
} }
@Test @Test
public void testLogin() throws Exception { public void testLogin() throws Exception {
// open | /webui/ | // open | /webui/ |
driver.get(baseUrl + "/webui/"); driver.get(baseUrl + "webui/");
// type | id=loginPanel_grdLogin_rowUser_txtUserId | SuperUser // type | id=loginPanel_grdLogin_rowUser_txtUserId | GardenAdmin
driver.findElement(By.id("loginPanel_grdLogin_rowUser_txtUserId")).clear(); driver.findElement(By.id("loginPanel_txtUserId")).clear();
driver.findElement(By.id("loginPanel_grdLogin_rowUser_txtUserId")).sendKeys("SuperUser"); driver.findElement(By.id("loginPanel_txtUserId")).sendKeys("GardenAdmin");
// fireEvent | id=loginPanel_grdLogin_rowUser_txtUserId | blur // fireEvent | id=loginPanel_grdLogin_rowUser_txtUserId | blur
// not needed for webdriver // not needed for webdriver
// type | id=loginPanel_grdLogin_rowPassword_txtPassword | System // type | id=loginPanel_grdLogin_rowPassword_txtPassword | GardenAdmin
driver.findElement(By.id("loginPanel_grdLogin_rowPassword_txtPassword")).clear(); driver.findElement(By.id("loginPanel_txtPassword")).clear();
driver.findElement(By.id("loginPanel_grdLogin_rowPassword_txtPassword")).sendKeys("System"); driver.findElement(By.id("loginPanel_txtPassword")).sendKeys("GardenAdmin");
// fireEvent | id=loginPanel_grdLogin_rowPassword_txtPassword | blur // fireEvent | id=loginPanel_grdLogin_rowPassword_txtPassword | blur
// not needed for webdriver // not needed for webdriver
// click | id=loginPanel_grdLogin_rowSelectRole_chkSelectRole-real | // click | id=loginPanel_grdLogin_rowSelectRole_chkSelectRole-real |
driver.findElement(By.id("loginPanel_grdLogin_rowSelectRole_chkSelectRole-real")).click(); driver.findElement(By.id("loginPanel_chkSelectRole-real")).click();
// click | loginPanel_Ok | 10 // click | loginPanel_Ok | 10
driver.findElement(By.id("loginPanel_Ok")).click(); driver.findElement(By.id("loginPanel_Ok")).click();
// waitForElementPresent | id=rolePanel_grdChooseRole_rowclient_lstClient-btn | // waitForElementPresent | id=rolePanel_grdChooseRole_rowclient_lstClient-btn |
for (int second = 0;; second++) { for (int second = 0;; second++) {
if (second >= 60) fail("timeout"); if (second >= 60) fail("timeout");
try { if (isElementPresent(By.id("rolePanel_grdChooseRole_rowclient_lstClient-btn"))) break; } catch (Exception e) {} try { if (isElementPresent(By.id("rolePanel_lstClient-btn"))) break; } catch (Exception e) {}
Thread.sleep(1000); Thread.sleep(1000);
} }
WebElement lstClient = driver.findElement(By.id("rolePanel_lstClient"));
if (lstClient != null && lstClient.isDisplayed()) {
// click | id=rolePanel_grdChooseRole_rowclient_lstClient-btn | // click | id=rolePanel_grdChooseRole_rowclient_lstClient-btn |
driver.findElement(By.id("rolePanel_grdChooseRole_rowclient_lstClient-btn")).click(); driver.findElement(By.id("rolePanel_lstClient-btn")).click();
// click | css=#rolePanel_grdChooseRole_rowclient_lstClient_GardenWorld > td.z-comboitem-text | // click | css=#rolePanel_grdChooseRole_rowclient_lstClient_GardenWorld > td.z-comboitem-text |
driver.findElement(By.cssSelector("#rolePanel_grdChooseRole_rowclient_lstClient_GardenWorld > td.z-comboitem-text")).click(); driver.findElement(By.cssSelector("#rolePanel_lstClient_GardenWorld > td.z-comboitem-text")).click();
Thread.sleep(1000); Thread.sleep(1000);
}
// click | id=rolePanel_grdChooseRole_rowRole_lstRole-btn | // click | id=rolePanel_grdChooseRole_rowRole_lstRole-btn |
driver.findElement(By.id("rolePanel_grdChooseRole_rowRole_lstRole-btn")).click(); driver.findElement(By.id("rolePanel_lstRole-btn")).click();
// click | css=#rolePanel_grdChooseRole_rowRole_lstRole_GardenWorld_Admin > td.z-comboitem-text | // click | css=#rolePanel_grdChooseRole_rowRole_lstRole_GardenWorld_Admin > td.z-comboitem-text |
driver.findElement(By.cssSelector("#rolePanel_grdChooseRole_rowRole_lstRole_GardenWorld_Admin > td.z-comboitem-text")).click(); driver.findElement(By.cssSelector("#rolePanel_lstRole_GardenWorld_Admin > td.z-comboitem-text")).click();
Thread.sleep(1000); Thread.sleep(1000);
// click | id=rolePanel_grdChooseRole_rowOrganisation_lstOrganisation-btn | // click | id=rolePanel_grdChooseRole_rowOrganisation_lstOrganisation-btn |
driver.findElement(By.id("rolePanel_grdChooseRole_rowOrganisation_lstOrganisation-btn")).click(); driver.findElement(By.id("rolePanel_lstOrganisation-btn")).click();
// click | css=#rolePanel_grdChooseRole_rowOrganisation_lstOrganisation_HQ > td.z-comboitem-text | // click | css=#rolePanel_grdChooseRole_rowOrganisation_lstOrganisation_HQ > td.z-comboitem-text |
driver.findElement(By.cssSelector("#rolePanel_grdChooseRole_rowOrganisation_lstOrganisation_HQ > td.z-comboitem-text")).click(); driver.findElement(By.cssSelector("#rolePanel_lstOrganisation_HQ > td.z-comboitem-text")).click();
// click | rolePanel_Ok | // click | rolePanel_Ok |
driver.findElement(By.id("rolePanel_Ok")).click(); driver.findElement(By.id("rolePanel_Ok")).click();
// waitForElementPresent | loginUserAndRole | // waitForElementPresent | loginUserAndRole |
@ -70,8 +73,8 @@ public class LoginTest {
try { if (isElementPresent(By.id("loginUserAndRole"))) break; } catch (Exception e) {} try { if (isElementPresent(By.id("loginUserAndRole"))) break; } catch (Exception e) {}
Thread.sleep(1000); Thread.sleep(1000);
} }
// assertText | loginUserAndRole | SuperUser@GardenWorld.HQ/GardenWorld Admin // assertText | loginUserAndRole | GardenAdmin@GardenWorld.HQ/GardenWorld Admin
assertEquals("SuperUser@GardenWorld.HQ/GardenWorld Admin", driver.findElement(By.id("loginUserAndRole")).getText()); assertEquals("GardenAdmin@GardenWorld.HQ/GardenWorld Admin", driver.findElement(By.id("loginUserAndRole")).getText());
} }
@After @After

8
ztl/.classpath Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="/idempiere.zk.selenium/lib/selenium-server-standalone-2.27.0.jar" sourcepath="/idempiere.zk.selenium/lib/selenium-server-2.27.0-srcs.jar"/>
<classpathentry kind="lib" path="lib/ztl-2.0.0-SNAPSHOT.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

17
ztl/.project Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ztl</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

18
ztl/Readme.txt Normal file
View File

@ -0,0 +1,18 @@
config.properties
- configuration file for running Ztl generator and Ztl test
ZtlGenerator.launch
- Eclipse launch configuration for Ztl generator
test
- Example test cases generated by Ztl generator
resource/test
- ztl test script
Notes
======
* You must change the "target" instance variable value to "" in the generated ztl java source
* Use the AdempiereIDGenerator and your browser's inspect element tool to find out the selector for the element that you need to access. Alternatively,
you can use the script created from Selenium IDE recording as a guide.

View File

@ -1,20 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication"> <launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/idempiere.zk.selenium/lib/ztl/ztl-2.0.0-SNAPSHOT.jar"/> <listEntry value="/ztl/lib/ztl-2.0.0-SNAPSHOT.jar"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="1"/> <listEntry value="1"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> <listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; javaProject=&quot;zk.test&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; javaProject=&quot;ztl&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;zk.test&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;ztl&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/zk.test/lib/ztl/commons-collections-3.2.1.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/ztl/lib/commons-lang-2.4.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/zk.test/lib/ztl/commons-lang-2.4.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/ztl/lib/velocity-1.7.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/zk.test/lib/ztl/velocity-1.7.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
</listAttribute> </listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> <booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.zkoss.ztl.util.ZtlGenerator"/> <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.zkoss.ztl.util.ZtlGenerator"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-src resource/ztl -dist src"/> <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-src resource -dist src"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="idempiere.zk.selenium"/> <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="ztl"/>
</launchConfiguration> </launchConfiguration>

View File

@ -2,7 +2,7 @@ server=http://127.0.0.1:8080
context-path=/webui context-path=/webui
delay=500 delay=500
action= action=
timeout=20000 timeout=10000
browser=firefox browser=firefox
granularity=1 granularity=1
leniency=1 leniency=1

View File

@ -1,8 +1,5 @@
ztl-2.0.0-SNAPSHOT.jar ztl-2.0.0-SNAPSHOT.jar
- for execution of ztl generator and ztl test cases - for execution of ztl generator and ztl test cases
selenium-server-standalone-2.25.0.jar
- for execution of ztl test cases
others others
- for execution of ztl generator - for execution of ztl generator

View File

@ -2,13 +2,17 @@
<case id="login"> <case id="login">
<client> <client>
<![CDATA[ <![CDATA[
type(jq("$loginPanel $txtUserId"), "SuperUser"); type(jq("$loginPanel $txtUserId"), "GardenAdmin");
type(jq("$loginPanel $txtPassword"), "System"); type(jq("$loginPanel $txtPassword"), "GardenAdmin");
click(widget(jq("$loginPanel $chkSelectRole")).$n("real")); click(widget(jq("$loginPanel $chkSelectRole")).$n("real"));
click(jq("$loginPanel $Ok")); click(jq("$loginPanel $Ok"));
waitResponse(); waitResponse();
JQuery lstClient = jq("$rolePanel $lstClient");
if (lstClient.exists() && lstClient.isVisible()) {
click(jq("$rolePanel $lstClient ~ .z-combobox-btn")); click(jq("$rolePanel $lstClient ~ .z-combobox-btn"));
click(jq("$rolePanel $lstClient $GardenWorld")); click(jq("$rolePanel $lstClient $GardenWorld"));
waitResponse();
}
click(jq("$rolePanel $lstRole ~ .z-combobox-btn")); click(jq("$rolePanel $lstRole ~ .z-combobox-btn"));
click(jq("$rolePanel $lstRole $GardenWorld\\\\ Admin")); click(jq("$rolePanel $lstRole $GardenWorld\\\\ Admin"));
waitResponse(); waitResponse();
@ -16,7 +20,7 @@
click(jq("$rolePanel $lstOrganisation $HQ")); click(jq("$rolePanel $lstOrganisation $HQ"));
click(jq("$rolePanel $Ok")); click(jq("$rolePanel $Ok"));
waitResponse(); waitResponse();
verifyEquals("SuperUser@GardenWorld.HQ/GardenWorld Admin", jq("$loginUserAndRole").text()); verifyEquals("GardenAdmin@GardenWorld.HQ/GardenWorld Admin", jq("$loginUserAndRole").text());
]]> ]]>
</client> </client>
</case> </case>

View File

@ -5,14 +5,14 @@
Description: Description:
History: History:
Dec, 6, 2012 17:09:52 PM Dec, 11, 2012 00:52:22 AM
Copyright (C) 2012 Potix Corporation. All Rights Reserved. Copyright (C) 2012 Potix Corporation. All Rights Reserved.
This program is distributed under Apache License Version 2.0 in the hope that This program is distributed under Apache License Version 2.0 in the hope that
it will be useful, but WITHOUT ANY WARRANTY. it will be useful, but WITHOUT ANY WARRANTY.
*/ */
package zk.ztl.test; package test;
import org.junit.Test; import org.junit.Test;
import org.zkoss.ztl.Element; import org.zkoss.ztl.Element;
import org.zkoss.ztl.JQuery; import org.zkoss.ztl.JQuery;
@ -32,7 +32,7 @@ public class LoginTest extends ZKClientTestCase {
public LoginTest() { public LoginTest() {
target = ""; target = "";
browsers = getBrowsers("firefox"); browsers = getBrowsers("firefox");
_timeout = 20000; _timeout = 10000;
caseID = getClass().getSimpleName(); caseID = getClass().getSimpleName();
} }
@ -53,13 +53,17 @@ public class LoginTest extends ZKClientTestCase {
/** start **/ /** start **/
/** client code **/ /** client code **/
type(jq("$loginPanel $txtUserId"), "SuperUser"); type(jq("$loginPanel $txtUserId"), "GardenAdmin");
type(jq("$loginPanel $txtPassword"), "System"); type(jq("$loginPanel $txtPassword"), "GardenAdmin");
click(widget(jq("$loginPanel $chkSelectRole")).$n("real")); click(widget(jq("$loginPanel $chkSelectRole")).$n("real"));
click(jq("$loginPanel $Ok")); click(jq("$loginPanel $Ok"));
waitResponse(); waitResponse();
JQuery lstClient = jq("$rolePanel $lstClient");
if (lstClient.exists() && lstClient.isVisible()) {
click(jq("$rolePanel $lstClient ~ .z-combobox-btn")); click(jq("$rolePanel $lstClient ~ .z-combobox-btn"));
click(jq("$rolePanel $lstClient $GardenWorld")); click(jq("$rolePanel $lstClient $GardenWorld"));
waitResponse();
}
click(jq("$rolePanel $lstRole ~ .z-combobox-btn")); click(jq("$rolePanel $lstRole ~ .z-combobox-btn"));
click(jq("$rolePanel $lstRole $GardenWorld\\\\ Admin")); click(jq("$rolePanel $lstRole $GardenWorld\\\\ Admin"));
waitResponse(); waitResponse();
@ -67,7 +71,7 @@ public class LoginTest extends ZKClientTestCase {
click(jq("$rolePanel $lstOrganisation $HQ")); click(jq("$rolePanel $lstOrganisation $HQ"));
click(jq("$rolePanel $Ok")); click(jq("$rolePanel $Ok"));
waitResponse(); waitResponse();
verifyEquals("SuperUser@GardenWorld.HQ/GardenWorld Admin", jq("$loginUserAndRole").text()); verifyEquals("GardenAdmin@GardenWorld.HQ/GardenWorld Admin", jq("$loginUserAndRole").text());
/** end **/ /** end **/
} catch (SeleniumException e) { } catch (SeleniumException e) {