From d442f2c04d9888135569dc54070f646515497c7e Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Wed, 19 Dec 2012 16:23:33 +0800 Subject: [PATCH] IDEMPIERE-92 - Integrate Selenium. Make more class test ready. Added test case for IDEMPIERE-520. --- .../ZkSuite/ProductionTest/content.txt | 32 ++++++++ .../ZkSuite/ProductionTest/properties.xml | 12 +++ .../ProductionTestEmptyTable/content.txt | 31 ++++++++ .../ProductionTestEmptyTable/properties.xml | 12 +++ .../webui/adwindow/ADWindowContent.java | 1 + .../adwindow/AbstractADWindowContent.java | 3 + .../adempiere/webui/adwindow/BreadCrumb.java | 1 + .../src/fitlibrary/zk/ZkFixture.java | 48 ++++++++++++ .../src/test/AbstractTestCase.java | 38 ++++++++++ .../src/test/ProductionTest.java | 75 +++++++++++++++++++ .../src/test/SelectTabTest.java | 2 +- 11 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 fitnesse/FitNesseRoot/ZkSuite/ProductionTest/content.txt create mode 100644 fitnesse/FitNesseRoot/ZkSuite/ProductionTest/properties.xml create mode 100644 fitnesse/FitNesseRoot/ZkSuite/ProductionTestEmptyTable/content.txt create mode 100644 fitnesse/FitNesseRoot/ZkSuite/ProductionTestEmptyTable/properties.xml create mode 100644 org.idempiere.ui.zk.selenium/src/test/ProductionTest.java diff --git a/fitnesse/FitNesseRoot/ZkSuite/ProductionTest/content.txt b/fitnesse/FitNesseRoot/ZkSuite/ProductionTest/content.txt new file mode 100644 index 0000000000..8acfa8a923 --- /dev/null +++ b/fitnesse/FitNesseRoot/ZkSuite/ProductionTest/content.txt @@ -0,0 +1,32 @@ +'''IDEMPIERE-520 Master/Detail bugs found using Production window''' + +!include -c ZkGardenAdminLogin + +!define windowId {$Production__Single_Product__1} + +|''open window''|!-Production (Single Product)-!| +|''wait response''| +|''window''|${windowId}|''click toolbar''|!-BtnNew-!| +|''wait response''| +|''element exists''|${windowId} $detailPane @tabbox| +|''lookup''|${windowId} $Production $M_Product_ID|''search''|!-PatioSet-!| +|''wait response''| +|''with''|${windowId} $Production $ProductionQty @decimalbox|''set text''|!-1-!| +|''window''|${windowId}|''click toolbar''|!-BtnSave-!| +|''wait response''| +|''window message''|${windowId}|is|!-Record saved-!| +|''window''|${windowId}|''click detail toolbar''|!-BtnNew-!| +|''wait response''| +|''text of''|${windowId} $recordInfo|is|!-+*1/1-!| +|''window''|${windowId}|''click toolbar''|!-BtnParentRecord-!| +|''wait response''| +|''window''|${windowId}|''click process button''|!-CreateFrom-!| +|''wait response''| +|''click''|${windowId} @window[title="Create Production"] $Ok| +|''wait response''| +|''window''|${windowId}|''click detail toolbar''|!-BtnEdit-!| +|''wait response''| +|''element visible''|${windowId} $detailPane @tab| +|''window''|${windowId}|''next record''| +|''wait response''| +|''element invisible''|${windowId} $detailPane @tab| diff --git a/fitnesse/FitNesseRoot/ZkSuite/ProductionTest/properties.xml b/fitnesse/FitNesseRoot/ZkSuite/ProductionTest/properties.xml new file mode 100644 index 0000000000..3e87512357 --- /dev/null +++ b/fitnesse/FitNesseRoot/ZkSuite/ProductionTest/properties.xml @@ -0,0 +1,12 @@ + + + true + true + true + true + true + true + + true + true + diff --git a/fitnesse/FitNesseRoot/ZkSuite/ProductionTestEmptyTable/content.txt b/fitnesse/FitNesseRoot/ZkSuite/ProductionTestEmptyTable/content.txt new file mode 100644 index 0000000000..2ebfb7bcb0 --- /dev/null +++ b/fitnesse/FitNesseRoot/ZkSuite/ProductionTestEmptyTable/content.txt @@ -0,0 +1,31 @@ +'''IDEMPIERE-520 Master/Detail bugs found using Production window''' + +!include -c ZkGardenAdminLogin + +!define windowId {$Production__Single_Product__1} + +|''open window''|!-Production (Single Product)-!| +|''wait response''| +|''element exists''|${windowId} $detailPane @tabbox| +|''lookup''|${windowId} $Production $M_Product_ID|''search''|!-PatioSet-!| +|''wait response''| +|''with''|${windowId} $Production $ProductionQty @decimalbox|''set text''|!-1-!| +|''window''|${windowId}|''click toolbar''|!-BtnSave-!| +|''wait response''| +|''window message''|${windowId}|is|!-Record saved-!| +|''window''|${windowId}|''click detail toolbar''|!-BtnNew-!| +|''wait response''| +|''text of''|${windowId} $recordInfo|is|!-+*1/1-!| +|''window''|${windowId}|''click toolbar''|!-BtnParentRecord-!| +|''wait response''| +|''window''|${windowId}|''click process button''|!-CreateFrom-!| +|''wait response''| +|''click''|${windowId} @window[title="Create Production"] $Ok| +|''wait response''| +|''window''|${windowId}|''click detail toolbar''|!-BtnEdit-!| +|''wait response''| +|''element visible''|${windowId} $detailPane @tab| +|''window''|${windowId}|''next record''| +|''wait response''| +|''element invisible''|${windowId} $detailPane @tab| + diff --git a/fitnesse/FitNesseRoot/ZkSuite/ProductionTestEmptyTable/properties.xml b/fitnesse/FitNesseRoot/ZkSuite/ProductionTestEmptyTable/properties.xml new file mode 100644 index 0000000000..3e87512357 --- /dev/null +++ b/fitnesse/FitNesseRoot/ZkSuite/ProductionTestEmptyTable/properties.xml @@ -0,0 +1,12 @@ + + + true + true + true + true + true + true + + true + true + diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java index 48ea779551..5f57941945 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java @@ -92,6 +92,7 @@ public class ADWindowContent extends AbstractADWindowContent toolbar.setWindowNo(getWindowNo()); breadCrumb = new BreadCrumb(getWindowNo()); breadCrumb.setToolbarListener(this); + breadCrumb.setId("breadCrumb"); div.appendChild(breadCrumb); //status bar diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java index c3d383bd17..6dc1fafce8 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java @@ -33,6 +33,7 @@ import java.util.TreeMap; import java.util.logging.Level; import org.adempiere.util.Callback; +import org.adempiere.webui.AdempiereIdGenerator; import org.adempiere.webui.AdempiereWebUI; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.WArchive; @@ -232,6 +233,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements { /** Initalise toolbar */ toolbar = new ADWindowToolbar(getWindowNo()); + toolbar.setId("windowToolbar"); toolbar.addListener(this); statusBar = new StatusBar(); @@ -2374,6 +2376,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements { Clients.showBusy(getComponent(), " "); final WCreateFromWindow window = (WCreateFromWindow) cf.getWindow(); + window.setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, AdempiereIdGenerator.escapeId(window.getTitle())); window.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() { @Override public void onEvent(Event event) throws Exception { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/BreadCrumb.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/BreadCrumb.java index db84e85855..0c0539f127 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/BreadCrumb.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/BreadCrumb.java @@ -132,6 +132,7 @@ public class BreadCrumb extends Div implements EventListener { btnRecordInfo.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Who"))); btnRecordInfo.addEventListener(Events.ON_CLICK, this); btnRecordInfo.setSclass("breadcrumb-record-info link"); + btnRecordInfo.setId("recordInfo"); toolbar.appendChild(btnRecordInfo); btnNext = createButton("Next", "Next", "Next"); toolbar.appendChild(btnNext); diff --git a/org.idempiere.ui.zk.selenium/src/fitlibrary/zk/ZkFixture.java b/org.idempiere.ui.zk.selenium/src/fitlibrary/zk/ZkFixture.java index 17f25b78d1..8a8d1bb139 100644 --- a/org.idempiere.ui.zk.selenium/src/fitlibrary/zk/ZkFixture.java +++ b/org.idempiere.ui.zk.selenium/src/fitlibrary/zk/ZkFixture.java @@ -98,6 +98,54 @@ public class ZkFixture extends SpiderFixture { return (String) widget.eval(webDriver, "getSelectedTab().getLabel()"); } + //--- Search (lookup) -- + @SimpleAction(wiki = "|''lookup''|xpath, id or other locator|''search''|value|", tooltip = "Search lookup with value.") + public void lookupSearch(String locator, String value) { + Widget widget = new Widget(locator + " @textbox"); + WebElement element = widget.findElement(webDriver); + element.click(); + widget.execute(webDriver, "setValue('"+value+"')"); + widget.execute(webDriver, "fireOnChange()"); + } + + // ---- window ( tab ) --- + @SimpleAction(wiki = "|''open window''|menu label|", tooltip = "Open window with label.") + public void openWindow(String label) { + comboboxSelectItem("$treeSearchCombo", label); + } + + @SimpleAction(wiki = "|''window''|xpath, id or other locator|''click process button''|button id|", tooltip = "Click a window's process button.") + public void windowClickProcessButton(String windowLocator, String btnId) { + click(windowLocator + " $windowToolbar $BtnProcess"); + waitResponse(); + click("@window[instanceName=\"processButtonPopup\"] $" + btnId); + } + + @SimpleAction(wiki = "|''window''|xpath, id or other locator|''click toolbar''|value|", tooltip = "Click a window's toolbar button") + public void windowClickToolbar(String windowLocator, String toolbarButtonId) { + click(windowLocator + " $windowToolbar $" + toolbarButtonId); + } + + @SimpleAction(wiki = "|''window''|xpath, id or other locator|''click detail toolbar''|value|", tooltip = "Click the detailpane's toolbar button") + public void windowClickDetailToolbar(String windowLocator, String toolbarButtonId) { + click(windowLocator + " $detailPane $" + toolbarButtonId + ":visible"); + } + + @SimpleAction(wiki = "|''window message''|xpath, id or other locator|", tooltip = "Current status message display for a window") + public String windowMessage(String windowLocator) { + return webDriver.findElement(Zk.jq(windowLocator +" $messages @label")).getText(); + } + + @SimpleAction(wiki = "|''window''|xpath, id or other locator|''next record''|value|", tooltip = "Navigate to next record.") + public void windowNextRecord(String windowLocator) { + click(windowLocator+" $breadCrumb $Next"); + } + + @SimpleAction(wiki = "|''window''|xpath, id or other locator|''previous record''|value|", tooltip = "Navigate to previous record.") + public void windowPreviousRecord(String windowLocator) { + click(windowLocator+" $breadCrumb $Previous"); + } + // -------- Wait Ajax Response ----- @SimpleAction(wiki = "|''wait response''|", tooltip = "Wait for ajax response with default timeout value.") public void waitResponse() { diff --git a/org.idempiere.ui.zk.selenium/src/test/AbstractTestCase.java b/org.idempiere.ui.zk.selenium/src/test/AbstractTestCase.java index e52f66023b..88537adca9 100644 --- a/org.idempiere.ui.zk.selenium/src/test/AbstractTestCase.java +++ b/org.idempiere.ui.zk.selenium/src/test/AbstractTestCase.java @@ -53,6 +53,14 @@ public class AbstractTestCase { element.click(); } + protected void search(String locator, String label) { + Widget widget = new Widget(locator + " @textbox"); + WebElement element = widget.findElement(driver); + element.click(); + widget.execute(driver, "setValue('"+label+"')"); + widget.execute(driver, "fireOnChange()"); + } + protected void selectCheckbox(String locator, boolean select) { final WebElement element = driver.findElement(Zk.jq("$"+locator+" ~ input")); if (element.isSelected()) { @@ -204,6 +212,36 @@ public class AbstractTestCase { return false; } } + + protected void openWindow(String label) { + comboboxSelectItem("$treeSearchCombo", label); + } + + protected void clickProcessButton(String windowId, String btnId) { + clickButton("$"+windowId + " $windowToolbar $BtnProcess"); + waitResponse(); + clickButton("@window[instanceName=\"processButtonPopup\"] $" + btnId); + } + + protected void clickToolbarButton(String windowId, String toolBarButtonId) { + clickButton("$" + windowId + " $windowToolbar $" + toolBarButtonId); + } + + protected void clickDetailToolbarButton(String windowId, String toolBarButtonId) { + clickButton("$" + windowId + " $detailPane $" + toolBarButtonId + ":visible"); + } + + protected WebElement getWindowMessageLabel(String windowId) { + return driver.findElement(Zk.jq("$"+windowId +" $messages @label")); + } + + protected void nextRecord(String windowId) { + clickButton("$"+windowId+" $breadCrumb $Next"); + } + + protected void previousRecord(String windowId) { + clickButton("$"+windowId+" $breadCrumb $Previous"); + } @After public void tearDown() throws Exception { diff --git a/org.idempiere.ui.zk.selenium/src/test/ProductionTest.java b/org.idempiere.ui.zk.selenium/src/test/ProductionTest.java new file mode 100644 index 0000000000..9191f0f182 --- /dev/null +++ b/org.idempiere.ui.zk.selenium/src/test/ProductionTest.java @@ -0,0 +1,75 @@ +package test; + +import org.idempiere.ui.zk.selenium.Zk; +import org.junit.Test; + +import static org.junit.Assert.*; +import org.openqa.selenium.WebElement; + +/** + * Test case for http://jira.idempiere.com/browse/IDEMPIERE-520 + * @author hengsin + * + */ +public class ProductionTest extends AbstractTestCase { + + @Test + public void testIDempiere520() throws Exception { + login(); + + String windowId = "Production__Single_Product__1"; + + openWindow("Production (Single Product)"); + + waitResponse(); + + //check detail is shown for new record + WebElement element = driver.findElement(Zk.jq("$"+windowId+" $detailPane @tabbox")); + + assertTrue(element != null && element.isDisplayed()); + + search("$"+windowId+" $Production $M_Product_ID", "PatioSet"); + waitResponse(); + + type("$"+windowId+" $Production $ProductionQty @decimalbox", "1"); + + + clickToolbarButton(windowId, "BtnSave"); + waitResponse(); + + //verify save successfull + element = getWindowMessageLabel(windowId); + assertTrue("Record saved".equals(element.getText())); + + clickDetailToolbarButton(windowId, "BtnNew"); + + //verify +*1/1 for is shown for new record + waitResponse(); + element = driver.findElement(Zk.jq("$"+windowId+" $recordInfo")); + assertEquals("+*1/1", element.getText()); + + //test for npe + clickToolbarButton(windowId, "BtnParentRecord"); + waitResponse(); + + //create production lines + clickProcessButton(windowId, "CreateFrom"); + waitResponse(); + clickButton("$"+windowId+" @window[title=\"Create Production\"] $Ok"); + waitResponse(); + + clickDetailToolbarButton(windowId, "BtnEdit"); + waitResponse(); + + //verify qc tab visible for first record + element = driver.findElement(Zk.jq("$"+windowId+" $detailPane @tab")); + assertTrue(element != null && element.isDisplayed()); + + nextRecord(windowId); + waitResponse(); + + //verify qc tab is invisible for first record + element = driver.findElement(Zk.jq("$"+windowId+" $detailPane @tab")); + assertTrue(element == null || !element.isDisplayed()); + } +} diff --git a/org.idempiere.ui.zk.selenium/src/test/SelectTabTest.java b/org.idempiere.ui.zk.selenium/src/test/SelectTabTest.java index d580ca30bd..f5fe8b26d5 100644 --- a/org.idempiere.ui.zk.selenium/src/test/SelectTabTest.java +++ b/org.idempiere.ui.zk.selenium/src/test/SelectTabTest.java @@ -16,7 +16,7 @@ public class SelectTabTest extends AbstractTestCase { public void testSelectTab() throws Exception { login(); waitResponse(); - comboboxSelectItem("$treeSearchCombo", "Product"); + openWindow("Product"); waitResponse(); clickButton("$findWindow_1 $simpleSearch $btnOk"); waitResponse();