From b7b0b16476332e28a780fbae66d36c542174e114 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Sat, 1 Jul 2023 14:24:58 +0200 Subject: [PATCH] IDEMPIERE-5750 Error when switching to tab when choosing a language other than English (#1920) * IDEMPIERE-5750 Error when switching to tab when choosing a language other than English * - avoid usage of AdempiereIdGenerator.escapeId when not ZkUnitTest --- .../org/compiere/model/SystemProperties.java | 46 +++++++++++++++++++ .../server.product.functionaltest.launch | 2 +- .../adempiere/webui/AdempiereIdGenerator.java | 8 ++++ .../adempiere/webui/adwindow/ADSortTab.java | 4 +- .../adempiere/webui/adwindow/ADTabpanel.java | 6 ++- .../adwindow/AbstractADWindowContent.java | 9 ++-- .../adempiere/webui/component/Combobox.java | 17 ++++--- .../adempiere/webui/component/Messagebox.java | 27 ++++++----- .../webui/desktop/TabbedDesktop.java | 9 ++-- .../org/adempiere/webui/panel/RolePanel.java | 25 ++++++---- .../webui/panel/ValidateMFAPanel.java | 9 ++-- 11 files changed, 122 insertions(+), 40 deletions(-) create mode 100644 org.adempiere.base/src/org/compiere/model/SystemProperties.java diff --git a/org.adempiere.base/src/org/compiere/model/SystemProperties.java b/org.adempiere.base/src/org/compiere/model/SystemProperties.java new file mode 100644 index 0000000000..99e77f892b --- /dev/null +++ b/org.adempiere.base/src/org/compiere/model/SystemProperties.java @@ -0,0 +1,46 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - Carlos Ruiz - globalqss - bxservice * + **********************************************************************/ + +package org.compiere.model; + +/** + * Collection of System properties used in iDempiere + * + * @author Carlos Ruiz - globalqss - bxservice + */ + +public class SystemProperties { + + public static final String ZkUnitTest = "ZkUnitTest"; + + /** + * ZkUnitTest=true to define if the component ids must be generated using AdempiereIdGenerator.escapeId + * @return + */ + public static boolean isZkUnitTest() { + return "true".equals(System.getProperty(ZkUnitTest)); + } + +} diff --git a/org.adempiere.server-feature/server.product.functionaltest.launch b/org.adempiere.server-feature/server.product.functionaltest.launch index 4a5d6de341..a52a9600ca 100644 --- a/org.adempiere.server-feature/server.product.functionaltest.launch +++ b/org.adempiere.server-feature/server.product.functionaltest.launch @@ -53,7 +53,7 @@ - + diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereIdGenerator.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereIdGenerator.java index af5e1b108f..1368109221 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereIdGenerator.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereIdGenerator.java @@ -105,6 +105,14 @@ public class AdempiereIdGenerator implements IdGenerator { return name.toLowerCase(); } + /** + * Generate an id with just alphanumeric characters + * This is used for ZkUnitTest that requires predictable iDs, f.e. Selenium + * WARNING: it doesn't work well with non-alphanumeric languages + * f.e. in Russian the translation for bank and account lead to the same id ____ + * @param prefix + * @return + */ public static String escapeId(String prefix) { Pattern pattern = Pattern.compile("[^a-zA-Z_0-9]"); Matcher matcher = pattern.matcher(prefix); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java index eefd7685c4..b16f0edac1 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java @@ -46,6 +46,7 @@ import org.compiere.model.MRole; import org.compiere.model.MSysConfig; import org.compiere.model.MTable; import org.compiere.model.PO; +import org.compiere.model.SystemProperties; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; @@ -303,7 +304,8 @@ public class ADSortTab extends Panel implements IADTabpanel ZKUpdateUtil.setVflex(yesList, true); ZKUpdateUtil.setVflex(noList, true); - setId(AdempiereIdGenerator.escapeId(gridTab.getName())); + if (SystemProperties.isZkUnitTest()) + setId(AdempiereIdGenerator.escapeId(gridTab.getName())); EventListener mouseListener = new EventListener() { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java index dd55b2faad..1ee8c90080 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java @@ -86,6 +86,7 @@ import org.compiere.model.MTree; import org.compiere.model.MTreeNode; import org.compiere.model.PO; import org.compiere.model.Query; +import org.compiere.model.SystemProperties; import org.compiere.model.X_AD_FieldGroup; import org.compiere.model.X_AD_ToolBarButton; import org.compiere.util.CCache; @@ -447,8 +448,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer this.dataBinder = new GridTabDataBinder(gridTab); this.getChildren().clear(); - - setId(AdempiereIdGenerator.escapeId(gridTab.getName())); + + if (SystemProperties.isZkUnitTest()) + setId(AdempiereIdGenerator.escapeId(gridTab.getName())); int AD_Tree_ID = 0; if (gridTab.isTreeTab()) 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 c6b6b24a75..28751305e6 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 @@ -112,6 +112,7 @@ import org.compiere.model.MUserPreference; import org.compiere.model.MWindow; import org.compiere.model.PO; import org.compiere.model.StateChangeEvent; +import org.compiere.model.SystemProperties; import org.compiere.model.X_AD_CtxHelp; import org.compiere.process.DocAction; import org.compiere.process.ProcessInfo; @@ -3699,7 +3700,8 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements if(cf.isInitOK()) { final WCreateFromWindow window = (WCreateFromWindow) cf.getWindow(); - window.setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, AdempiereIdGenerator.escapeId(window.getTitle())); + if (SystemProperties.isZkUnitTest()) + 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 { @@ -4132,8 +4134,9 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements ZKUpdateUtil.setHeight(infoWindow, height + "px"); } infoWindow.setContentStyle("overflow: auto"); - - infoWindow.setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, AdempiereIdGenerator.escapeId(infoWindow.getTitle())); + + if (SystemProperties.isZkUnitTest()) + infoWindow.setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, AdempiereIdGenerator.escapeId(infoWindow.getTitle())); infoWindow.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/component/Combobox.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Combobox.java index d812bceb59..44dcf663e4 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Combobox.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Combobox.java @@ -21,6 +21,7 @@ import java.util.List; import org.adempiere.webui.AdempiereIdGenerator; import org.adempiere.webui.LayoutUtils; +import org.compiere.model.SystemProperties; import org.zkoss.zk.au.out.AuScript; import org.zkoss.zk.ui.IdSpace; import org.zkoss.zk.ui.Page; @@ -112,9 +113,11 @@ public class Combobox extends org.zkoss.zul.Combobox implements IdSpace public Comboitem appendItem(String label) { ComboItem item = new ComboItem(label); - String id = AdempiereIdGenerator.escapeId(label); - if (getFellowIfAny(id) == null ) - item.setId(id); + if (SystemProperties.isZkUnitTest()) { + String id = AdempiereIdGenerator.escapeId(label); + if (getFellowIfAny(id) == null ) + item.setId(id); + } item.setParent(this); return item; } @@ -143,9 +146,11 @@ public class Combobox extends org.zkoss.zul.Combobox implements IdSpace */ public void appendItem(String name, Object value) { ComboItem item = new ComboItem(name, value); - String id = AdempiereIdGenerator.escapeId(name); - if (getFellowIfAny(id) == null) - item.setId(id); + if (SystemProperties.isZkUnitTest()) { + String id = AdempiereIdGenerator.escapeId(name); + if (getFellowIfAny(id) == null) + item.setId(id); + } this.appendChild(item); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java index 889cf73cda..9f611d6979 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java @@ -33,6 +33,7 @@ import org.adempiere.webui.factory.ButtonFactory; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; +import org.compiere.model.SystemProperties; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Util; @@ -376,20 +377,22 @@ public class Messagebox extends Window implements EventListener this.setSizable(true); this.setVisible(true); - String id = "MessageBox_"+AdempiereIdGenerator.escapeId(title); - //make sure id is unique - Page page = AEnv.getDesktop().getFirstPage(); - Component fellow = page.getFellowIfAny(id); - if (fellow != null) { - int count = 0; - String newId = null; - while (fellow != null) { - newId = id + "_" + ++count; - fellow = page.getFellowIfAny(newId); + if (SystemProperties.isZkUnitTest()) { + String id = "MessageBox_"+AdempiereIdGenerator.escapeId(title); + //make sure id is unique + Page page = AEnv.getDesktop().getFirstPage(); + Component fellow = page.getFellowIfAny(id); + if (fellow != null) { + int count = 0; + String newId = null; + while (fellow != null) { + newId = id + "_" + ++count; + fellow = page.getFellowIfAny(newId); + } + id = newId; } - id = newId; + this.setId(id); } - this.setId(id); AEnv.showCenterScreen(this); return returnValue; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/TabbedDesktop.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/TabbedDesktop.java index c29347f260..f900dbc11e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/TabbedDesktop.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/TabbedDesktop.java @@ -37,6 +37,7 @@ import org.compiere.model.MForm; import org.compiere.model.MInfoWindow; import org.compiere.model.MQuery; import org.compiere.model.MTask; +import org.compiere.model.SystemProperties; import org.compiere.util.Env; import org.compiere.wf.MWorkflow; import org.zkoss.util.media.AMedia; @@ -155,10 +156,12 @@ public abstract class TabbedDesktop extends AbstractDesktop { public void openWindow(int windowId, MQuery query, Callback callback) { final ADWindow adWindow = new ADWindow(Env.getCtx(), windowId, query); - final DesktopTabpanel tabPanel = new DesktopTabpanel(); - String id = AdempiereIdGenerator.escapeId(adWindow.getTitle()); + final DesktopTabpanel tabPanel = new DesktopTabpanel(); int windowNo = adWindow.getADWindowContent().getWindowNo(); - tabPanel.setId(id+"_"+windowNo); + if (SystemProperties.isZkUnitTest()) { + String id = AdempiereIdGenerator.escapeId(adWindow.getTitle()); + tabPanel.setId(id+"_"+windowNo); + } final Tab tab = windowContainer.addWindow(tabPanel, adWindow.getTitle(), true, DecorateInfo.get(adWindow)); tab.setClosable(false); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/RolePanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/RolePanel.java index e26d908eec..5620f687d4 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/RolePanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/RolePanel.java @@ -46,6 +46,7 @@ import org.adempiere.webui.window.LoginWindow; import org.compiere.model.MRole; import org.compiere.model.MSysConfig; import org.compiere.model.MUser; +import org.compiere.model.SystemProperties; import org.compiere.util.Env; import org.compiere.util.KeyNamePair; import org.compiere.util.Language; @@ -368,9 +369,11 @@ public class RolePanel extends Window implements EventListener, Deferrabl for(int i = 0; i < m_clientKNPairs.length; i++) { ComboItem ci = new ComboItem(m_clientKNPairs[i].getName(), m_clientKNPairs[i].getID()); - String id = AdempiereIdGenerator.escapeId(ci.getLabel()); - if (lstClient.getFellowIfAny(id) == null) - ci.setId(id); + if (SystemProperties.isZkUnitTest()) { + String id = AdempiereIdGenerator.escapeId(ci.getLabel()); + if (lstClient.getFellowIfAny(id) == null) + ci.setId(id); + } lstClient.appendChild(ci); if (m_clientKNPairs[i].getID().equals(initDefault)) lstClient.setSelectedItem(ci); @@ -425,9 +428,11 @@ public class RolePanel extends Window implements EventListener, Deferrabl for (int i = 0; i < roleKNPairs.length; i++) { ComboItem ci = new ComboItem(roleKNPairs[i].getName(), roleKNPairs[i].getID()); - String id = AdempiereIdGenerator.escapeId(ci.getLabel()); - if (lstRole.getFellowIfAny(id) == null) - ci.setId(id); + if (SystemProperties.isZkUnitTest()) { + String id = AdempiereIdGenerator.escapeId(ci.getLabel()); + if (lstRole.getFellowIfAny(id) == null) + ci.setId(id); + } lstRole.appendChild(ci); if (roleKNPairs[i].getID().equals(initDefault)) lstRole.setSelectedItem(ci); @@ -473,9 +478,11 @@ public class RolePanel extends Window implements EventListener, Deferrabl for(int i = 0; i < orgKNPairs.length; i++) { ComboItem ci = new ComboItem(orgKNPairs[i].getName(), orgKNPairs[i].getID()); - String id = AdempiereIdGenerator.escapeId(ci.getLabel()); - if (lstOrganisation.getFellowIfAny(id) == null) - ci.setId(id); + if (SystemProperties.isZkUnitTest()) { + String id = AdempiereIdGenerator.escapeId(ci.getLabel()); + if (lstOrganisation.getFellowIfAny(id) == null) + ci.setId(id); + } lstOrganisation.appendChild(ci); if(orgKNPairs[i].getID().equals(initDefault)) lstOrganisation.setSelectedItem(ci); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ValidateMFAPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ValidateMFAPanel.java index e7c34a09ed..4ccf57bb77 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ValidateMFAPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ValidateMFAPanel.java @@ -55,6 +55,7 @@ import org.compiere.model.MMFARegistration; import org.compiere.model.MSysConfig; import org.compiere.model.MUser; import org.compiere.model.PO; +import org.compiere.model.SystemProperties; import org.compiere.util.CLogger; import org.compiere.util.Env; import org.compiere.util.KeyNamePair; @@ -267,9 +268,11 @@ public class ValidateMFAPanel extends Window implements EventListener { m_autoCall = true; } ComboItem ci = new ComboItem(reg.getName() + " - " + method.getMethod(), reg.getMFA_Registration_ID()); - String id = AdempiereIdGenerator.escapeId(ci.getLabel()); - if (lstMFAMechanism.getFellowIfAny(id) == null) - ci.setId(id); + if (SystemProperties.isZkUnitTest()) { + String id = AdempiereIdGenerator.escapeId(ci.getLabel()); + if (lstMFAMechanism.getFellowIfAny(id) == null) + ci.setId(id); + } lstMFAMechanism.appendChild(ci); } lstMFAMechanism.setSelectedIndex(0);