From c6ac5780a7dbf4eaa82b1cfafcadcb70529a1bbf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=ABl=20Kr=C3=A4hemann?= <joel.kraehemann@frentix.com>
Date: Tue, 9 Oct 2012 14:38:59 +0200
Subject: [PATCH] OO-348: implemented test case.

---
 .../repository/FunctionalCatalogTest.java     |  89 +++++++-
 .../org/olat/util/FunctionalCourseUtil.java   | 205 +++++++++++++++++-
 .../util/FunctionalRepositorySiteUtil.java    |  27 ++-
 .../java/org/olat/util/FunctionalUtil.java    |  55 +++++
 4 files changed, 356 insertions(+), 20 deletions(-)

diff --git a/src/test/java/org/olat/repository/FunctionalCatalogTest.java b/src/test/java/org/olat/repository/FunctionalCatalogTest.java
index 2b6d555aa9e..b55f4efa353 100644
--- a/src/test/java/org/olat/repository/FunctionalCatalogTest.java
+++ b/src/test/java/org/olat/repository/FunctionalCatalogTest.java
@@ -28,6 +28,7 @@ import org.jboss.arquillian.container.test.api.RunAsClient;
 import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.jboss.arquillian.test.api.ArquillianResource;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -38,6 +39,7 @@ import org.olat.util.FunctionalCourseUtil;
 import org.olat.util.FunctionalRepositorySiteUtil;
 import org.olat.util.FunctionalUtil;
 import org.olat.util.FunctionalVOUtil;
+import org.olat.util.FunctionalRepositorySiteUtil.RepositorySiteAction;
 
 import com.thoughtworks.selenium.DefaultSelenium;
 
@@ -46,18 +48,24 @@ import com.thoughtworks.selenium.DefaultSelenium;
  * @author jkraehemann, joel.kraehemann@frentix.com, frentix.com
  */
 public class FunctionalCatalogTest {
+	public final static int COURSES = 2;
 	
 	public final static String[] SUBCATEGORY_PATHS = {
 		"/programming",
 		"/programming/c",
 		"/programming/java"
-		};
+	};
 	public final static String[] SUBCATEGORY_DESCRIPTIONS = {
 		"here you may find courses and resources related to programming",
 		"about the C programming language",
 		"about the Java programming language"
-		};
+	};
 	
+	public final static String[] SUBCATECORY_PATHS_INCLUDING_RESOURCE = {
+		SUBCATEGORY_PATHS[1],
+		SUBCATEGORY_PATHS[2]
+	};
+
 	@Deployment(testable = false)
 	public static WebArchive createDeployment() {
 		return ArquillianDeployments.createDeployment();
@@ -100,28 +108,87 @@ public class FunctionalCatalogTest {
 		 * prerequisites for test created via REST
 		 */
 		/* import wiki */
-		RepositoryEntryVO[] wikiVO = new RepositoryEntryVO[2]; 
+		RepositoryEntryVO[] wikiVO = new RepositoryEntryVO[COURSES]; 
 		
-		wikiVO[0] = functionalVOUtil.importWiki(deploymentUrl);
-		wikiVO[1] = functionalVOUtil.importWiki(deploymentUrl);
+		for(int i = 0; i < COURSES; i++){
+			wikiVO[i] = functionalVOUtil.importWiki(deploymentUrl);
+		}
 		
 		/* import course */
-		CourseVO[] courseVO = new CourseVO[2];
-		
-		courseVO[0] = functionalVOUtil.importEmptyCourse(deploymentUrl);
-		courseVO[1] = functionalVOUtil.importEmptyCourse(deploymentUrl);
+		CourseVO[] courseVO = new CourseVO[COURSES];
 		
+		for(int i = 0; i < COURSES; i++){
+			courseVO[i] = functionalVOUtil.importEmptyCourse(deploymentUrl);
+		}
+
 		/*
 		 * create or configure content
 		 */
+		/* create categories */
+		for(int i = 0; i < SUBCATEGORY_PATHS.length; i++){
+			String currentPath = SUBCATEGORY_PATHS[i];
+			String currentName = currentPath.substring(currentPath.lastIndexOf('/') + 1);
+			String currentDescription = SUBCATEGORY_DESCRIPTIONS[i];
+			
+			Assert.assertTrue(functionalRepositorySiteUtil.createCatalogSubcategory(browser, currentPath, currentName, currentDescription));
+		}
 		
-		//TODO:JK: implement me
+		/* edit course and publish thereby adding it to catalog  */
+		for(int i = 0; i < COURSES; i++){
+			/* open course in edit mode */	
+			Assert.assertTrue(functionalRepositorySiteUtil.openCourse(browser, courseVO[i].getRepoEntryKey()));
+			
+			Assert.assertTrue(functionalCourseUtil.openCourseEditor(browser));
+			
+			/* choose wiki */
+			String currentPath = SUBCATEGORY_PATHS[i];
+			String currentName = currentPath.substring(currentPath.lastIndexOf('/') + 1);
+			
+			Assert.assertTrue(functionalCourseUtil.createWiki(browser, currentName + " wiki", "colaborative " + currentName + " wiki"));
+			Assert.assertTrue(functionalCourseUtil.chooseWiki(browser, wikiVO[i].getKey()));
+			
+			/* publish course */
+			Assert.assertTrue(functionalCourseUtil.publishEntireCourse(browser, null, SUBCATEGORY_PATHS[i]));
+			
+			/* close course */
+			Assert.assertTrue(functionalCourseUtil.closeActiveTab(browser));
+		}
 		
 		/*
 		 * verify content
 		 */
+		/* open catalog */
+		Assert.assertTrue(functionalUtil.openSite(browser, FunctionalUtil.OlatSite.LEARNING_RESOURCES));
+		
+		Assert.assertTrue(functionalRepositorySiteUtil.openActionByMenuTree(browser, RepositorySiteAction.CATALOG));
 		
-		//TODO:JK: implement me
+		/* verify resources */
+		for(int i = 0; i < COURSES; i++){
+			String[] selectors = functionalRepositorySiteUtil.createCatalogSelectors(SUBCATECORY_PATHS_INCLUDING_RESOURCE[i]);
+			
+			for(String currentSelector: selectors){
+				/* click first course and retrieve business path */
+				StringBuffer selectorBuffer = new StringBuffer();
+				
+				selectorBuffer.append("xpath=//a[contains(@class, '")
+				.append(functionalRepositorySiteUtil.getCourseModuleIconCss())
+				.append("')]");
+				
+				browser.click(selectorBuffer.toString());
+				
+				functionalUtil.waitForPageToLoad(browser);
+				
+				String businessPath0 = functionalUtil.currentBusinessPath(browser);
+				
+				/* open course and retrieve business path */
+				functionalRepositorySiteUtil.openCourse(browser, courseVO[i].getRepoEntryKey());
+				
+				String businessPath1 = functionalUtil.currentBusinessPath(browser);
+				
+				/* assert collected business paths to be equal */
+				Assert.assertEquals(businessPath1, businessPath0);
+			}
+		}
 	}
 	
 }
diff --git a/src/test/java/org/olat/util/FunctionalCourseUtil.java b/src/test/java/org/olat/util/FunctionalCourseUtil.java
index 87752e9d50d..5e2f633da0a 100644
--- a/src/test/java/org/olat/util/FunctionalCourseUtil.java
+++ b/src/test/java/org/olat/util/FunctionalCourseUtil.java
@@ -21,6 +21,9 @@ package org.olat.util;
 
 import java.net.MalformedURLException;
 import java.net.URI;
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
@@ -35,6 +38,8 @@ import com.thoughtworks.selenium.Selenium;
 public class FunctionalCourseUtil {
 	private final static OLog log = Tracing.createLoggerFor(FunctionalCourseUtil.class);
 	
+	private final static Pattern categoryPattern = Pattern.compile("/([^/]+)");
+	
 	public final static String COURSE_RUN_CSS = "o_course_run";
 	public final static String COURSE_OPEN_EDITOR_CSS = "o_sel_course_open_editor";
 	
@@ -81,9 +86,15 @@ public class FunctionalCourseUtil {
 	public final static String FEED_CHOOSE_REPOSITORY_FILE_CSS = "o_sel_feed_choose_repofile";
 	public final static String MAP_CHOOSE_REPOSITORY_FILE_CSS = "o_sel_map_choose_repofile";
 	
+	public final static String REPOSITORY_POPUP_CSS = "o_sel_search_referenceable_entries";
+	
 	public final static String REPOSITORY_POPUP_CREATE_RESOURCE_CSS = "o_sel_repo_popup_create_resource";
 	public final static String REPOSITORY_POPUP_IMPORT_RESOURCE_CSS = "o_sel_repo_popup_import_resource";
 	
+	public final static String REPOSITORY_POPUP_ALL_RESOURCES_CSS = "o_sel_repo_popup_all_resources";
+	public final static String REPOSITORY_POPUP_MY_RESOURCES_CSS = "o_sel_repo_popup_my_resources";
+	public final static String REPOSITORY_POPUP_SEARCH_RESOURCES_CSS = "o_sel_repo_popup_search_resources";
+	
 	public final static String MAP_EDIT_CSS = "o_sel_edit_map";
 	
 	public final static String BLOG_NO_POSTS_CSS = "o_blog_no_posts";
@@ -312,7 +323,14 @@ public class FunctionalCourseUtil {
 	private String feedChooseRepositoryFileCss;
 	private String mapChooseRepositoryFileCss;
 
+	private String repositoryPopupCss;
+	
 	private String repositoryPopupCreateResourceCss;
+	private String repositoryPopupImportResourceCss;
+	
+	private String repositoryPopupAllResourcesCss;
+	private String repositoryPopupMyResourcesCss;
+	private String repositoryPopupSearchResourcesCss;
 	
 	private String mapEditCss;
 	
@@ -370,7 +388,14 @@ public class FunctionalCourseUtil {
 		setFeedChooseRepositoryFileCss(FEED_CHOOSE_REPOSITORY_FILE_CSS);
 		setMapChooseRepositoryFileCss(MAP_CHOOSE_REPOSITORY_FILE_CSS);
 		
+		setRepositoryPopupCss(REPOSITORY_POPUP_CSS);
+		
 		setRepositoryPopupCreateResourceCss(REPOSITORY_POPUP_CREATE_RESOURCE_CSS);
+		setRepositoryPopupImportResourceCss(REPOSITORY_POPUP_IMPORT_RESOURCE_CSS);
+		
+		setRepositoryPopupAllResourcesCss(REPOSITORY_POPUP_ALL_RESOURCES_CSS);
+		setRepositoryPopupMyResourcesCss(REPOSITORY_POPUP_MY_RESOURCES_CSS);
+		setRepositoryPopupSearchResourcesCss(REPOSITORY_POPUP_SEARCH_RESOURCES_CSS);
 		
 		setMapEditCss(MAP_EDIT_CSS);
 		
@@ -403,7 +428,7 @@ public class FunctionalCourseUtil {
 	public boolean open(Selenium browser, int nth){
 		StringBuffer selectorBuffer = new StringBuffer();
 
-		selectorBuffer.append("xpath=//ul[contains(@class, 'b_tree_l1')]//li[")
+		selectorBuffer.append("xpath=(//ul[contains(@class, 'b_tree_l1')]//li)[")
 		.append(nth + 1)
 		.append("]//a");
 		
@@ -412,6 +437,30 @@ public class FunctionalCourseUtil {
 		return(true);
 	}
 	
+	/**
+	 * @param browser
+	 * @param alias
+	 * @param nth
+	 * @return true on success
+	 * 
+	 * Opens the nth course element of course node type specified by alias in the current course.
+	 */
+	public boolean open(Selenium browser, CourseNodeAlias alias, int nth){
+		StringBuffer selectorBuffer = new StringBuffer();
+
+		selectorBuffer.append("xpath=(//ul[contains(@class, 'b_tree_l1')]//li]//a[contains(@class, '")
+		.append(alias.getIconCss())
+		.append("')])[")
+		.append(nth + 1)
+		.append("]");
+		
+		browser.click(selectorBuffer.toString());
+		
+		functionalUtil.waitForPageToLoad(browser);
+		
+		return(true);
+	}
+	
 	/**
 	 * @param browser
 	 * @param courseId
@@ -632,9 +681,35 @@ public class FunctionalCourseUtil {
 	 * Creates xpath selectors to select catalog within the tree.
 	 */
 	public String[] createCatalogSelectors(String path){
-		//TODO:JK: implement me
+		if(path == null ||
+				!path.startsWith("/")){
+			return(null);
+		}
 		
-		return(null);
+		Matcher categoryMatcher = categoryPattern.matcher(path);
+		ArrayList<String> selectors = new ArrayList<String>();
+		
+		StringBuffer selectorBuffer = new StringBuffer();
+		
+		selectorBuffer.append("xpath=//li//a[contains(@class, '")
+		.append(functionalUtil.getTreeNodeAnchorCss())
+		.append("')]//a");
+		
+		selectors.add(selectorBuffer.toString());
+		
+		while(categoryMatcher.find()){
+			StringBuffer selector = new StringBuffer();
+			
+			selector.append("xpath=//li//a[contains(@class, '")
+			.append(functionalUtil.getTreeNodeAnchorCss())
+			.append("')]//a//span[text()='")
+			.append(categoryMatcher.group(1))
+			.append("')]/..");
+			
+			selectors.add(selector.toString());
+		}
+		
+		return((String[]) selectors.toArray());
 	}
 	
 	/**
@@ -1236,6 +1311,69 @@ public class FunctionalCourseUtil {
 		return(functionalUtil.openContentTab(browser, tab.ordinal()));
 	}
 	
+	private boolean chooseRepositoryResource(Selenium browser, String chooseRepositoryCss, long key){
+		/* click on "choose, create or import file" button */
+		StringBuffer selectorBuffer = new StringBuffer();
+
+		selectorBuffer.append("xpath=//a[contains(@class, '")
+		.append(chooseRepositoryCss)
+		.append("')]");
+		
+		functionalUtil.waitForPageToLoadElement(browser, selectorBuffer.toString());
+		browser.click(selectorBuffer.toString());
+		
+		functionalUtil.waitForPageToLoad(browser);
+		
+		/* click search link */
+		selectorBuffer = new StringBuffer();
+		
+		selectorBuffer.append("xpath=//a[contains(@class, '")
+		.append(getRepositoryPopupSearchResourcesCss())
+		.append("')]");
+		
+		functionalUtil.waitForPageToLoadElement(browser, selectorBuffer.toString());
+		browser.click(selectorBuffer.toString());
+		
+		/* type key and search */
+		selectorBuffer = new StringBuffer();
+		
+		selectorBuffer.append("xpath=//div[contains(@class, '")
+		.append(FunctionalRepositorySiteUtil.SearchField.ID.getEntryCss())
+		.append("')]//input[@type='text']");
+		
+		functionalUtil.waitForPageToLoadElement(browser, selectorBuffer.toString());
+		browser.type(selectorBuffer.toString(), Long.toString(key));
+		
+		selectorBuffer = new StringBuffer();
+		
+		selectorBuffer.append("xpath=(//div[contains(@class, '")
+		.append(getRepositoryPopupCss())
+		.append("')]//a[contains(@class, '")
+		.append(functionalUtil.getButtonCss())
+		.append("')])[last()]");
+		
+		functionalUtil.waitForPageToLoadElement(browser, selectorBuffer.toString());
+		browser.click(selectorBuffer.toString());
+		
+		/* choose resource */
+		selectorBuffer = new StringBuffer();
+		
+		selectorBuffer.append("xpath=//div[contains(@class, '")
+		.append(FunctionalRepositorySiteUtil.SearchField.ID.getEntryCss())
+		.append("')]//tr[contains(@class, '")
+		.append(functionalUtil.getTableFirstChildCss())
+		.append("') and contains(@class, '")
+		.append(functionalUtil.getTableLastChildCss())
+		.append("')]//td[contains(@class, '")
+		.append(functionalUtil.getTableLastChildCss())
+		.append("')]//a");
+		
+		functionalUtil.waitForPageToLoadElement(browser, selectorBuffer.toString());
+		browser.click(selectorBuffer.toString());
+		
+		return(true);
+	}
+	
 	/**
 	 * @param browser
 	 * @param chooseRepositoryCss
@@ -1331,6 +1469,23 @@ public class FunctionalCourseUtil {
 		return(true);
 	}
 	
+	/**
+	 * @param browser
+	 * @param wikiId
+	 * @return
+	 * 
+	 * Choose an existing wiki.
+	 */
+	public boolean chooseWiki(Selenium browser, long wikiId){
+		if(!openCourseEditorWikiTab(browser, CourseEditorWikiTab.LEARNING_CONTENT))
+			return(false);
+		
+		if(!chooseRepositoryResource(browser, getWikiChooseRepositoryFileCss(), wikiId)){
+			return(false);
+		}
+		
+		return(true);
+	}
 	/**
 	 * @param browser
 	 * @param title
@@ -1696,6 +1851,14 @@ public class FunctionalCourseUtil {
 		this.mapChooseRepositoryFileCss = mapChooseRepositoryFileCss;
 	}
 
+	public String getRepositoryPopupCss() {
+		return repositoryPopupCss;
+	}
+
+	public void setRepositoryPopupCss(String repositoryPopupCss) {
+		this.repositoryPopupCss = repositoryPopupCss;
+	}
+
 	public String getRepositoryPopupCreateResourceCss() {
 		return repositoryPopupCreateResourceCss;
 	}
@@ -1704,6 +1867,42 @@ public class FunctionalCourseUtil {
 		this.repositoryPopupCreateResourceCss = repositoryPopupCreateResourceCss;
 	}
 
+	public String getRepositoryPopupImportResourceCss() {
+		return repositoryPopupImportResourceCss;
+	}
+
+	public void setRepositoryPopupImportResourceCss(
+			String repositoryPopupImportResourceCss) {
+		this.repositoryPopupImportResourceCss = repositoryPopupImportResourceCss;
+	}
+
+	public String getRepositoryPopupAllResourcesCss() {
+		return repositoryPopupAllResourcesCss;
+	}
+
+	public void setRepositoryPopupAllResourcesCss(
+			String repositoryPopupAllResourcesCss) {
+		this.repositoryPopupAllResourcesCss = repositoryPopupAllResourcesCss;
+	}
+
+	public String getRepositoryPopupMyResourcesCss() {
+		return repositoryPopupMyResourcesCss;
+	}
+
+	public void setRepositoryPopupMyResourcesCss(
+			String repositoryPopupMyResourcesCss) {
+		this.repositoryPopupMyResourcesCss = repositoryPopupMyResourcesCss;
+	}
+
+	public String getRepositoryPopupSearchResourcesCss() {
+		return repositoryPopupSearchResourcesCss;
+	}
+
+	public void setRepositoryPopupSearchResourcesCss(
+			String repositoryPopupSearchResourcesCss) {
+		this.repositoryPopupSearchResourcesCss = repositoryPopupSearchResourcesCss;
+	}
+
 	public String getMapEditCss() {
 		return mapEditCss;
 	}
diff --git a/src/test/java/org/olat/util/FunctionalRepositorySiteUtil.java b/src/test/java/org/olat/util/FunctionalRepositorySiteUtil.java
index f6848077ab1..5a427dd9406 100644
--- a/src/test/java/org/olat/util/FunctionalRepositorySiteUtil.java
+++ b/src/test/java/org/olat/util/FunctionalRepositorySiteUtil.java
@@ -20,6 +20,7 @@
 package org.olat.util;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -73,6 +74,8 @@ public class FunctionalRepositorySiteUtil {
 	public final static String CATALOG_SUBCATEGORY_ICON_CSS = "o_catalog_sub_icon";
 	public final static String CATALOG_SUBCATEGORY_LIST_CSS = "o_catalog_itemlist";
 	
+	public final static String COURSE_MODULE_ICON_CSS = "o_CourseModule_icon";
+	
 	public enum Column {
 		AC,
 		TYPE,
@@ -277,6 +280,8 @@ public class FunctionalRepositorySiteUtil {
 	private String catalogSubcategoryListCss;
 	private String catalogSubcategoryIconCss;
 	
+	private String courseModuleIconCss;
+	
 	private String importCourseCss;
 	private String importCPLearningContentCss;
 	private String importScormCss;
@@ -348,6 +353,8 @@ public class FunctionalRepositorySiteUtil {
 		setCatalogSubcategoryListCss(CATALOG_SUBCATEGORY_LIST_CSS);
 		setCatalogSubcategoryIconCss(CATALOG_SUBCATEGORY_ICON_CSS);
 		
+		setCourseModuleIconCss(COURSE_MODULE_ICON_CSS);
+		
 		setImportCourseCss(IMPORT_COURSE_CSS);
 		setImportCPLearningContentCss(IMPORT_CP_LEARNING_CONTENT_CSS);
 		setImportScormCss(IMPORT_SCORM_CSS);
@@ -398,23 +405,23 @@ public class FunctionalRepositorySiteUtil {
 		}
 		
 		Matcher categoryMatcher = categoryPattern.matcher(path);
-		String[] selectors = new String[categoryMatcher.groupCount()];
+		ArrayList<String> selectors = new ArrayList<String>();
 		
-		for(int i = 0; categoryMatcher.find(); i++){
+		while(categoryMatcher.find()){
 			StringBuffer selector = new StringBuffer();
 			
 			selector.append("xpath=//div[contains(@class, '")
 			.append(getCatalogSubcategoryListCss())
 			.append("')]//a//span[contains(@class, '")
 			.append(getCatalogSubcategoryIconCss())
-			.append("' and text()='")
+			.append("') and text()='")
 			.append(categoryMatcher.group(1))
-			.append("')]/..");
+			.append("']/..");
 			
-			selectors[i] = selector.toString();
+			selectors.add(selector.toString());
 		}
 		
-		return(selectors);
+		return((String[]) selectors.toArray());
 	}
 	
 	/**
@@ -1295,6 +1302,14 @@ public class FunctionalRepositorySiteUtil {
 		this.catalogSubcategoryIconCss = catalogSubcategoryIconCss;
 	}
 
+	public String getCourseModuleIconCss() {
+		return courseModuleIconCss;
+	}
+
+	public void setCourseModuleIconCss(String courseModuleIconCss) {
+		this.courseModuleIconCss = courseModuleIconCss;
+	}
+
 	public String getImportCourseCss() {
 		return importCourseCss;
 	}
diff --git a/src/test/java/org/olat/util/FunctionalUtil.java b/src/test/java/org/olat/util/FunctionalUtil.java
index e9a07e7857a..3b4bb5d050e 100644
--- a/src/test/java/org/olat/util/FunctionalUtil.java
+++ b/src/test/java/org/olat/util/FunctionalUtil.java
@@ -104,7 +104,12 @@ public class FunctionalUtil {
 	
 	public final static String MCE_CONTENT_BODY_CSS = "mceContentBody";
 	
+	public final static String BUTTON_CSS = "b_button";
 	public final static String BUTTON_DIRTY_CSS = "b_button_dirty";
+	public final static String TABLE_FIRST_CHILD_CSS = "b_first_child";
+	public final static String TABLE_LAST_CHILD_CSS = "b_last_child";
+	public final static String TREE_NODE_ANCHOR_CSS = "x-tree-node-anchor";
+	public final static String TREE_NODE_CSS = "x-tree-node";
 	
 	public final static String NOTIFICATION_BOX_CSS = "o_sel_info_message";
 	
@@ -145,7 +150,12 @@ public class FunctionalUtil {
 	
 	private String mceContentBodyCss;
 	
+	private String buttonCss;
 	private String buttonDirtyCss;
+	private String tableFirstChildCss;
+	private String tableLastChildCss;
+	private String treeNodeAnchorCss;
+	private String treeNodeCss;
 	
 	private FunctionalHomeSiteUtil functionalHomeSiteUtil;
 	private FunctionalGroupsSiteUtil functionalGroupsSiteUtil;
@@ -205,7 +215,12 @@ public class FunctionalUtil {
 		
 		mceContentBodyCss = MCE_CONTENT_BODY_CSS;
 		
+		buttonCss = BUTTON_CSS;
 		buttonDirtyCss = BUTTON_DIRTY_CSS;
+		tableFirstChildCss = TABLE_FIRST_CHILD_CSS;
+		tableLastChildCss = TABLE_LAST_CHILD_CSS;
+		treeNodeAnchorCss = TREE_NODE_ANCHOR_CSS;
+		treeNodeCss = TREE_NODE_CSS;
 		
 		functionalHomeSiteUtil = new FunctionalHomeSiteUtil(this);
 		functionalGroupsSiteUtil = new FunctionalGroupsSiteUtil(this);
@@ -1178,6 +1193,14 @@ public class FunctionalUtil {
 		this.functionalAdministrationSiteUtil = functionalAdministrationSiteUtil;
 	}
 
+	public String getButtonCss() {
+		return buttonCss;
+	}
+
+	public void setButtonCss(String buttonCss) {
+		this.buttonCss = buttonCss;
+	}
+
 	public String getButtonDirtyCss() {
 		return buttonDirtyCss;
 	}
@@ -1185,4 +1208,36 @@ public class FunctionalUtil {
 	public void setButtonDirtyCss(String buttonDirtyCss) {
 		this.buttonDirtyCss = buttonDirtyCss;
 	}
+
+	public String getTableFirstChildCss() {
+		return tableFirstChildCss;
+	}
+
+	public void setTableFirstChildCss(String tableFirstChildCss) {
+		this.tableFirstChildCss = tableFirstChildCss;
+	}
+
+	public String getTableLastChildCss() {
+		return tableLastChildCss;
+	}
+
+	public void setTableLastChildCss(String tableLastChildCss) {
+		this.tableLastChildCss = tableLastChildCss;
+	}
+
+	public String getTreeNodeAnchorCss() {
+		return treeNodeAnchorCss;
+	}
+
+	public void setTreeNodeAnchorCss(String treeNodeAnchorCss) {
+		this.treeNodeAnchorCss = treeNodeAnchorCss;
+	}
+
+	public String getTreeNodeCss() {
+		return treeNodeCss;
+	}
+
+	public void setTreeNodeCss(String treeNodeCss) {
+		this.treeNodeCss = treeNodeCss;
+	}
 }
-- 
GitLab