From 8e4cff9c50d575aee2db03a23c6183139e7ba6e6 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Fri, 7 Apr 2017 08:41:31 +0200
Subject: [PATCH] OO-2676: simplify html code of calendar event editor and
 repository info editor, replace synchronized in velocity with a
 ConcurentHashSet to reduce lock contention, remove double update method for
 groups...

---
 .../ui/CalendarEntryDetailsController.java    |  7 +--
 .../calendar/ui/_content/calEditDetails.html  |  1 -
 .../calendar/ui/_content/calEditMain.html     |  1 -
 .../org/olat/core/gui/render/Renderer.java    |  2 +-
 .../gui/render/velocity/VelocityHelper.java   | 14 ++---
 .../olat/group/manager/BusinessGroupDAO.java  | 18 ++----
 .../RepositoryEditDescriptionController.java  | 60 +++++++++----------
 .../olat/group/test/BusinessGroupDAOTest.java |  2 +-
 .../olat/modules/ims/cp/CPManagerTest.java    | 60 +++----------------
 .../olat/selenium/page/core/CalendarPage.java |  3 +-
 .../selenium/page/graphene/OOGraphene.java    | 24 ++++++++
 11 files changed, 76 insertions(+), 116 deletions(-)
 delete mode 100644 src/main/java/org/olat/commons/calendar/ui/_content/calEditDetails.html
 delete mode 100644 src/main/java/org/olat/commons/calendar/ui/_content/calEditMain.html

diff --git a/src/main/java/org/olat/commons/calendar/ui/CalendarEntryDetailsController.java b/src/main/java/org/olat/commons/calendar/ui/CalendarEntryDetailsController.java
index 8cf4e04a726..fc175aa48f9 100644
--- a/src/main/java/org/olat/commons/calendar/ui/CalendarEntryDetailsController.java
+++ b/src/main/java/org/olat/commons/calendar/ui/CalendarEntryDetailsController.java
@@ -65,7 +65,7 @@ public class CalendarEntryDetailsController extends BasicController {
 	private Collection<KalendarRenderWrapper> availableCalendars;
 	private boolean isNew, isReadOnly;
 	private KalendarEvent kalendarEvent;
-	private VelocityContainer mainVC, linkVC;
+	private VelocityContainer linkVC;
 	private TabbedPane pane;
 	private CalendarEntryForm eventForm;
 	private CloseableModalController cmc;
@@ -87,11 +87,8 @@ public class CalendarEntryDetailsController extends BasicController {
 		this.kalendarEvent = kalendarEvent;
 		this.isNew = isNew;
 		
-		mainVC = createVelocityContainer ("calEditMain");
-		mainVC.contextPut("caller", caller);
 		pane = new TabbedPane("pane", getLocale());
 		pane.addListener(this);
-		mainVC.put("pane", pane);
 		
 		eventForm = new CalendarEntryForm(ureq, wControl, kalendarEvent, calendarWrapper, availableCalendars, isNew);
 		listenTo(eventForm);
@@ -124,7 +121,7 @@ public class CalendarEntryDetailsController extends BasicController {
 		}
 		
 		// wrap everything in a panel
-		putInitialPanel(mainVC);
+		putInitialPanel(pane);
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/commons/calendar/ui/_content/calEditDetails.html b/src/main/java/org/olat/commons/calendar/ui/_content/calEditDetails.html
deleted file mode 100644
index 2fa94c18bb4..00000000000
--- a/src/main/java/org/olat/commons/calendar/ui/_content/calEditDetails.html
+++ /dev/null
@@ -1 +0,0 @@
-$r.render("eventForm")
\ No newline at end of file
diff --git a/src/main/java/org/olat/commons/calendar/ui/_content/calEditMain.html b/src/main/java/org/olat/commons/calendar/ui/_content/calEditMain.html
deleted file mode 100644
index 70a7e0cd8df..00000000000
--- a/src/main/java/org/olat/commons/calendar/ui/_content/calEditMain.html
+++ /dev/null
@@ -1 +0,0 @@
-$r.render("pane")
\ No newline at end of file
diff --git a/src/main/java/org/olat/core/gui/render/Renderer.java b/src/main/java/org/olat/core/gui/render/Renderer.java
index 86ffc447c22..96db777b724 100644
--- a/src/main/java/org/olat/core/gui/render/Renderer.java
+++ b/src/main/java/org/olat/core/gui/render/Renderer.java
@@ -287,7 +287,7 @@ public class Renderer {
 	 */
 	public static String getComponentPrefix(Component comp) {
 		String did = comp.getDispatchID();
-		return "o_c"+did;
+		return "o_c".concat(did);
 	}
 	
 	/**
diff --git a/src/main/java/org/olat/core/gui/render/velocity/VelocityHelper.java b/src/main/java/org/olat/core/gui/render/velocity/VelocityHelper.java
index 96da0de6f73..b1022cb0e99 100644
--- a/src/main/java/org/olat/core/gui/render/velocity/VelocityHelper.java
+++ b/src/main/java/org/olat/core/gui/render/velocity/VelocityHelper.java
@@ -28,8 +28,9 @@ package org.olat.core.gui.render.velocity;
 
 import java.io.StringWriter;
 import java.io.Writer;
-import java.util.HashSet;
 import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.velocity.Template;
 import org.apache.velocity.app.VelocityEngine;
@@ -51,7 +52,7 @@ public class VelocityHelper extends LogDelegator {
 
 	private VelocityEngine ve;
 	
-	private HashSet<String> resourcesNotFound = new HashSet<String>(128);
+	private Set<String> resourcesNotFound = ConcurrentHashMap.newKeySet();
 
 	/**
 	 * 
@@ -131,10 +132,7 @@ public class VelocityHelper extends LogDelegator {
 				String themedTemplatePath = sb.toString();
 
 				// check cache
-				boolean notFound;
-				synchronized (resourcesNotFound) { //o_clusterOK by:fj
-					notFound = resourcesNotFound.contains(themedTemplatePath);
-				}
+				boolean notFound = resourcesNotFound.contains(themedTemplatePath);
 				
 				if (!notFound) {
 					// never tried before -> try to load it
@@ -142,9 +140,7 @@ public class VelocityHelper extends LogDelegator {
 						// remember not found (since velocity doesn't) then try fallback.
 						// this will happen once for each theme when a resource does not exist in its themed variant but only in the default theme.
 						if (!Settings.isDebuging()) {
-							synchronized (resourcesNotFound) { //o_clusterOK by:fj
-								resourcesNotFound.add(themedTemplatePath);
-							}
+							resourcesNotFound.add(themedTemplatePath);
 						} // for debugging, allow introduction of themed files without restarting the application
 					} else {
 						// template exists -> load it
diff --git a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
index 47134e92332..1264910c079 100644
--- a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
+++ b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
@@ -240,10 +240,13 @@ public class BusinessGroupDAO {
 		return groups.get(0);
 	}
 	
+	/**
+	 * Work with the hibernate session
+	 * @param group
+	 * @return
+	 */
 	public BusinessGroup merge(BusinessGroup group) {
-		EntityManager em = dbInstance.getCurrentEntityManager();
-		BusinessGroup mergedGroup = em.merge(group);
-		return mergedGroup;
+		return dbInstance.getCurrentEntityManager().merge(group);
 	}
 	
 	/**
@@ -258,15 +261,6 @@ public class BusinessGroupDAO {
 		dbInstance.getCurrentEntityManager().remove(group.getBaseGroup());
 	}
 	
-	/**
-	 * Work with the hibernate session
-	 * @param group
-	 * @return
-	 */
-	public BusinessGroup update(BusinessGroup group) {
-		return dbInstance.getCurrentEntityManager().merge(group);
-	}
-	
 	public List<BusinessGroupMembership> getBusinessGroupsMembership(Collection<BusinessGroup> groups) {
 		List<Long> groupKeys = new ArrayList<>();
 		for(BusinessGroup group:groups) {
diff --git a/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java b/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java
index 93d51eb5cab..214b031b363 100644
--- a/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java
+++ b/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java
@@ -102,7 +102,7 @@ public class RepositoryEditDescriptionController extends FormBasicController {
 	private SingleSelection dateTypesEl, publicDatesEl;
 	private DateChooser startDateEl, endDateEl;
 	private FormSubmit submit;
-	private FormLayoutContainer descCont, privateDatesCont;
+	private FormLayoutContainer privateDatesCont;
 	
 	private static final String[] dateKeys = new String[]{ "none", "private", "public"};
 
@@ -125,7 +125,7 @@ public class RepositoryEditDescriptionController extends FormBasicController {
 	 * @param sourceEntry
 	 */
 	public RepositoryEditDescriptionController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry) {
-		super(ureq, wControl, "bgrep");
+		super(ureq, wControl);
 		setBasePackage(RepositoryService.class);
 		this.repositoryEntry = entry;
 		repoEntryType = repositoryEntry.getOlatResource().getResourceableTypeName();
@@ -138,27 +138,24 @@ public class RepositoryEditDescriptionController extends FormBasicController {
 
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
-		
-		descCont = FormLayoutContainer.createDefaultFormLayout("desc", getTranslator());
-		descCont.setFormContextHelp("Info Page: Add Meta Data");
-		descCont.setRootForm(mainForm);
-		formLayout.add("desc", descCont);
+		setFormContextHelp("Info Page: Add Meta Data");
+		formLayout.setElementCssClass("o_sel_edit_repositoryentry");
 
 		String id = repositoryEntry.getResourceableId() == null ? "-" : repositoryEntry.getResourceableId().toString();
-		uifactory.addStaticTextElement("cif.id", id, descCont);
+		uifactory.addStaticTextElement("cif.id", id, formLayout);
 		
 		String externalId = repositoryEntry.getExternalId();
 		if(StringHelper.containsNonWhitespace(externalId)) {
-			uifactory.addStaticTextElement("cif.externalid", externalId, descCont);
+			uifactory.addStaticTextElement("cif.externalid", externalId, formLayout);
 		}
 		
 		String extRef = repositoryEntry.getExternalRef();
 		if(StringHelper.containsNonWhitespace(repositoryEntry.getManagedFlagsString())) {
 			if(StringHelper.containsNonWhitespace(extRef)) {
-				uifactory.addStaticTextElement("cif.externalref", extRef, descCont);
+				uifactory.addStaticTextElement("cif.externalref", extRef, formLayout);
 			}
 		} else {
-			externalRef = uifactory.addTextElement("cif.externalref", "cif.externalref", 100, extRef, descCont);
+			externalRef = uifactory.addTextElement("cif.externalref", "cif.externalref", 100, extRef, formLayout);
 			externalRef.setHelpText(translate("cif.externalref.hover"));
 			externalRef.setHelpUrlForManualPage("Info Page#_identification");
 			externalRef.setDisplaySize(30);
@@ -169,7 +166,7 @@ public class RepositoryEditDescriptionController extends FormBasicController {
 			initalAuthor = userManager.getUserDisplayName(initalAuthor);
 		}
 		initalAuthor = StringHelper.escapeHtml(initalAuthor);
-		uifactory.addStaticTextElement("cif.initialAuthor", initalAuthor, descCont);
+		uifactory.addStaticTextElement("cif.initialAuthor", initalAuthor, formLayout);
 		// Add resource type
 		String typeName = null;
 		OLATResource res = repositoryEntry.getOlatResource();
@@ -183,21 +180,21 @@ public class RepositoryEditDescriptionController extends FormBasicController {
 		} else {
 			typeDisplay = translate("cif.type.na");
 		}
-		uifactory.addStaticTextElement("cif.type", typeDisplay, descCont);
+		uifactory.addStaticTextElement("cif.type", typeDisplay, formLayout);
 		
-		uifactory.addSpacerElement("spacer1", descCont, false);
+		uifactory.addSpacerElement("spacer1", formLayout, false);
 
-		displayName = uifactory.addTextElement("cif.displayname", "cif.displayname", 100, repositoryEntry.getDisplayname(), descCont);
+		displayName = uifactory.addTextElement("cif.displayname", "cif.displayname", 100, repositoryEntry.getDisplayname(), formLayout);
 		displayName.setDisplaySize(30);
 		displayName.setMandatory(true);
 		displayName.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.title));
 
-		authors = uifactory.addTextElement("cif.authors", "cif.authors", 255, repositoryEntry.getAuthors(), descCont);
+		authors = uifactory.addTextElement("cif.authors", "cif.authors", 255, repositoryEntry.getAuthors(), formLayout);
 		authors.setDisplaySize(60);
 		
-		language = uifactory.addTextElement("cif.mainLanguage", "cif.mainLanguage", 16, repositoryEntry.getMainLanguage(), descCont);
+		language = uifactory.addTextElement("cif.mainLanguage", "cif.mainLanguage", 16, repositoryEntry.getMainLanguage(), formLayout);
 		
-		location = uifactory.addTextElement("cif.location", "cif.location", 255, repositoryEntry.getLocation(), descCont);
+		location = uifactory.addTextElement("cif.location", "cif.location", 255, repositoryEntry.getLocation(), formLayout);
 		location.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.location));
 		
 		RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler(repositoryEntry);
@@ -209,11 +206,11 @@ public class RepositoryEditDescriptionController extends FormBasicController {
 		
 		String desc = (repositoryEntry.getDescription() != null ? repositoryEntry.getDescription() : " ");
 		description = uifactory.addRichTextElementForStringData("cif.description", "cif.description",
-				desc, 10, -1, false, mediaContainer, null, descCont, ureq.getUserSession(), getWindowControl());
+				desc, 10, -1, false, mediaContainer, null, formLayout, ureq.getUserSession(), getWindowControl());
 		description.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.description));
 		description.getEditorConfiguration().setFileBrowserUploadRelPath("media");
 
-		uifactory.addSpacerElement("spacer2", descCont, false);
+		uifactory.addSpacerElement("spacer2", formLayout, false);
 
 		if(CourseModule.getCourseTypeName().equals(repoEntryType)) {
 			String[] dateValues = new String[] {
@@ -221,7 +218,7 @@ public class RepositoryEditDescriptionController extends FormBasicController {
 					translate("cif.dates.private"),
 					translate("cif.dates.public")	
 			};
-			dateTypesEl = uifactory.addRadiosVertical("cif.dates", descCont, dateKeys, dateValues);
+			dateTypesEl = uifactory.addRadiosVertical("cif.dates", formLayout, dateKeys, dateValues);
 			dateTypesEl.setElementCssClass("o_sel_repo_lifecycle_type");
 			if(repositoryEntry.getLifecycle() == null) {
 				dateTypesEl.select("none", true);
@@ -261,13 +258,13 @@ public class RepositoryEditDescriptionController extends FormBasicController {
 					}
 					publicValues[count++] = sb.toString();
 			}
-			publicDatesEl = uifactory.addDropdownSingleselect("cif.public.dates", descCont, publicKeys, publicValues, null);
+			publicDatesEl = uifactory.addDropdownSingleselect("cif.public.dates", formLayout, publicKeys, publicValues, null);
 	
 			String privateDatePage = velocity_root + "/cycle_dates.html";
 			privateDatesCont = FormLayoutContainer.createCustomFormLayout("private.date", getTranslator(), privateDatePage);
 			privateDatesCont.setRootForm(mainForm);
 			privateDatesCont.setLabel("cif.private.dates", null);
-			descCont.add("private.date", privateDatesCont);
+			formLayout.add("private.date", privateDatesCont);
 			
 			startDateEl = uifactory.addDateChooser("date.start", "cif.date.start", null, privateDatesCont);
 			startDateEl.setElementCssClass("o_sel_repo_lifecycle_validfrom");
@@ -291,39 +288,39 @@ public class RepositoryEditDescriptionController extends FormBasicController {
 			}
 	
 			updateDatesVisibility();
-			uifactory.addSpacerElement("spacer3", descCont, false);
+			uifactory.addSpacerElement("spacer3", formLayout, false);
 			
-			expenditureOfWork = uifactory.addTextElement("cif.expenditureOfWork", "cif.expenditureOfWork", 100, repositoryEntry.getExpenditureOfWork(), descCont);
+			expenditureOfWork = uifactory.addTextElement("cif.expenditureOfWork", "cif.expenditureOfWork", 100, repositoryEntry.getExpenditureOfWork(), formLayout);
 			expenditureOfWork.setExampleKey("details.expenditureOfWork.example", null);
 
 			String obj = (repositoryEntry.getObjectives() != null ? repositoryEntry.getObjectives() : " ");
 			objectives = uifactory.addRichTextElementForStringData("cif.objectives", "cif.objectives",
-					obj, 10, -1, false, mediaContainer, null, descCont, ureq.getUserSession(), getWindowControl());
+					obj, 10, -1, false, mediaContainer, null, formLayout, ureq.getUserSession(), getWindowControl());
 			objectives.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.objectives));
 			objectives.getEditorConfiguration().setFileBrowserUploadRelPath("media");
 			
 			
 			String req = (repositoryEntry.getRequirements() != null ? repositoryEntry.getRequirements() : " ");
 			requirements = uifactory.addRichTextElementForStringData("cif.requirements", "cif.requirements",
-					req, 10, -1,  false, mediaContainer, null, descCont, ureq.getUserSession(), getWindowControl());
+					req, 10, -1,  false, mediaContainer, null, formLayout, ureq.getUserSession(), getWindowControl());
 			requirements.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.requirements));
 			requirements.getEditorConfiguration().setFileBrowserUploadRelPath("media");
 			requirements.setMaxLength(2000);
 			
 			String cred = (repositoryEntry.getCredits() != null ? repositoryEntry.getCredits() : " ");
 			credits = uifactory.addRichTextElementForStringData("cif.credits", "cif.credits",
-					cred, 10, -1,  false, mediaContainer, null, descCont, ureq.getUserSession(), getWindowControl());
+					cred, 10, -1,  false, mediaContainer, null, formLayout, ureq.getUserSession(), getWindowControl());
 			credits.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.credits));
 			credits.getEditorConfiguration().setFileBrowserUploadRelPath("media");
 			credits.setMaxLength(2000);
 			
-			uifactory.addSpacerElement("spacer4", descCont, false);
+			uifactory.addSpacerElement("spacer4", formLayout, false);
 		}
 		
 		boolean managed = RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.details);
 		
 		VFSLeaf img = repositoryManager.getImage(repositoryEntry);
-		fileUpload = uifactory.addFileElement(getWindowControl(), "rentry.pic", "rentry.pic", descCont);
+		fileUpload = uifactory.addFileElement(getWindowControl(), "rentry.pic", "rentry.pic", formLayout);
 		fileUpload.setExampleKey("rentry.pic.example", new String[] {RepositoryManager.PICTURE_WIDTH + "x" + (RepositoryManager.PICTURE_HEIGHT)});
 		fileUpload.setMaxUploadSizeKB(picUploadlimitKB, null, null);
 		fileUpload.setPreview(ureq.getUserSession(), true);
@@ -337,7 +334,7 @@ public class RepositoryEditDescriptionController extends FormBasicController {
 		fileUpload.limitToMimeType(imageMimeTypes, "cif.error.mimetype", new String[]{ imageMimeTypes.toString()} );
 
 		VFSLeaf movie = repositoryService.getIntroductionMovie(repositoryEntry);
-		movieUpload = uifactory.addFileElement(getWindowControl(), "rentry.movie", "rentry.movie", descCont);
+		movieUpload = uifactory.addFileElement(getWindowControl(), "rentry.movie", "rentry.movie", formLayout);
 		movieUpload.setExampleKey("rentry.movie.example", new String[] {"3:2"});
 		movieUpload.setMaxUploadSizeKB(movieUploadlimitKB, null, null);
 		movieUpload.setPreview(ureq.getUserSession(), true);
@@ -371,7 +368,6 @@ public class RepositoryEditDescriptionController extends FormBasicController {
 				privateDatesCont.setVisible(true);
 			}
 		}
-		descCont.setDirty(true);
 	}
 
 	@Override
diff --git a/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java b/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java
index 58f531d8ef1..5099065eabe 100644
--- a/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java
+++ b/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java
@@ -318,7 +318,7 @@ public class BusinessGroupDAOTest extends OlatTestCase {
 		group.setDescription("gdio-2-desc");
 
 		//update business group (semantic of Hibernate before JPA)
-		BusinessGroup updatedGroup = businessGroupDao.update(group);
+		BusinessGroup updatedGroup = businessGroupDao.merge(group);
 		Assert.assertNotNull(updatedGroup);
 		Assert.assertEquals(group, updatedGroup);
 		Assert.assertEquals("gdio-2-desc", updatedGroup.getDescription());
diff --git a/src/test/java/org/olat/modules/ims/cp/CPManagerTest.java b/src/test/java/org/olat/modules/ims/cp/CPManagerTest.java
index 359ca0dbef0..992ff62b6b4 100644
--- a/src/test/java/org/olat/modules/ims/cp/CPManagerTest.java
+++ b/src/test/java/org/olat/modules/ims/cp/CPManagerTest.java
@@ -30,6 +30,7 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.olat.core.id.OLATResourceable;
@@ -91,28 +92,12 @@ public class CPManagerTest extends OlatTestCase {
 		CPItem item = orga.getFirstItem();
 		assertEquals(PAGE_TITLE, item.getTitle());
 	}
-	@Test
-	public void testCreateNewCP() {
-	// Tested through setup. Foundation for the other tests.
-	}
-	@Test
-	public void testIsSingleUsedResource() {
-	// mgr.isSingleUsedResource(res, cp);
-	}
+
 	@Test
 	public void testAddBlankPage() {
 		final String pageTitle = "the blank page";
 		String ident = mgr.addBlankPage(cp, pageTitle);
-		assertNotNull(ident);
-		
-	}
-	@Test
-	public void testUpdatePage() {
-	// TODO:GW impl
-	}
-	@Test
-	public void testAddElement() {
-	// TODO:GW impl
+		assertNotNull(ident);	
 	}
 
 	public void testAddElementAfter() {
@@ -120,61 +105,30 @@ public class CPManagerTest extends OlatTestCase {
 		mgr.addElementAfter(cp, newItem, ITEM_ID);
 		assertTrue("The new item wasn't inserted at the second position.", newItem.getPosition() == 1);
 	}
-	@Test
-	public void testRemoveElement() {
-	// TODO:GW impl
-	}
-	@Test
-	public void testMoveElement() {
-	// TODO:GW impl
-	}
 
-	public void testCopyElement() {
-	// TODO:GW impl
-	}
-	@Test
-	public void testGetDocument() {
-	// TODO:GW impl
-	}
 	@Test
 	public void testGetItemTitle() {
 		String title = mgr.getItemTitle(cp, ITEM_ID);
 		assertNotNull(title);
 		assertEquals(PAGE_TITLE, title);
 	}
-	@Test
-	public void testGetTreeDataModel() {
-	// TODO:GW impl
-	}
-	@Test
-	public void testGetFirstOrganizationInManifest() {
-	// TODO:GW impl
-	}
 
-	public void testGetFirstPageToDisplay() {
-	// this method basically just returns the first element in the cp
-	}
 	@Test
 	public void testGetPageByItemId() {
 		String href = mgr.getPageByItemId(cp, ITEM_ID);
 		VFSItem file = cp.getRootDir().resolve(href);
 		assertNotNull("The file path doesn't lead to a file.", file);
 	}
+	
 	@Test
 	public void testWriteToFile() {
 		mgr.writeToFile(cp); // Throws exception on failure
 	}
+	
 	@Test
 	public void testWriteToZip() {
-		// Substract 1s = 1000ms from now to make sure the time is before execution
-		long before = System.currentTimeMillis() - 1000;
 		VFSLeaf zip = mgr.writeToZip(cp);
-		assertNotNull("The zip file wasn't created properly", zip);
-		assertTrue("The last modified date of the zip file wasn't updated", zip.getLastModified() > before);
+		Assert.assertNotNull("The zip file wasn't created properly", zip);
+		Assert.assertTrue("The zip file cannot be empty", zip.getSize() > 0);
 	}
-	@Test
-	public void testGetElementByIdentifier() {
-	// TODO:GW impl
-	}
-
 }
diff --git a/src/test/java/org/olat/selenium/page/core/CalendarPage.java b/src/test/java/org/olat/selenium/page/core/CalendarPage.java
index ff3e1062697..0fbf4b5aaf9 100644
--- a/src/test/java/org/olat/selenium/page/core/CalendarPage.java
+++ b/src/test/java/org/olat/selenium/page/core/CalendarPage.java
@@ -166,7 +166,8 @@ public class CalendarPage {
 		OOGraphene.waitElement(dayBy, 5, browser);
 		browser.findElement(dayBy).click();
 		
-		OOGraphene.waitingALittleBit();
+		OOGraphene.waitElementUntilNotVisible(datePickerBy, 5, browser);
+		//OOGraphene.waitingALittleBit();
 		return this;
 	}
 	
diff --git a/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java b/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java
index 0148fb5491a..b240ff7d47a 100644
--- a/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java
+++ b/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java
@@ -99,6 +99,18 @@ public class OOGraphene {
 			.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(element).is().not().present();
 	}
 	
+	/**
+	 * Wait until the element is not visible.
+	 * 
+	 * @param element
+	 * @param timeoutInSeconds
+	 * @param browser
+	 */
+	public static void waitElementUntilNotVisible(By element, int timeoutInSeconds, WebDriver browser) {
+		Graphene.waitModel(browser).withTimeout(timeoutInSeconds, TimeUnit.SECONDS)
+			.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(element).is().not().visible();
+	}
+	
 	/**
 	 * Wait until the element is visible.
 	 * 
@@ -145,6 +157,18 @@ public class OOGraphene {
 			.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(element).is().present();
 	}
 	
+	/**
+	 * The method is very, very experimental and not reliable. Only for research purpose.
+	 * 
+	 * @param by
+	 * @param browser
+	 */
+	public static void waitElementInViewport(By by, WebDriver browser) {
+		Graphene.waitModel(browser).withTimeout(5, TimeUnit.SECONDS)
+			.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS)
+			.until(new InViewportPredicate(by));
+	}
+	
 	public static void waitGui(WebDriver browser) {
 		Graphene.waitGui(browser);
 	}
-- 
GitLab