From a1340ebb81aee296503ef30082452b6d825dbfc0 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Tue, 27 Jun 2017 21:38:00 +0200
Subject: [PATCH] OO-2836: add selenium to test hiden section in QTI 2.1 (see
 OO-2820), hardened open modal dialog and wizard, upgrade drone, remove a lot
 of @Drone...

---
 pom.xml                                       |   2 +-
 .../AssessmentSectionEditorController.java    |   1 +
 ...tSectionExpertOptionsEditorController.java |   2 +
 ...essmentSectionOptionsEditorController.java |   1 +
 .../java/org/olat/selenium/ImsQTI21Test.java  | 108 ++++++++++++++++++
 .../org/olat/selenium/page/LoginPage.java     |   6 +-
 .../olat/selenium/page/NavigationPage.java    |  38 +++---
 .../olat/selenium/page/core/CalendarPage.java |  12 +-
 .../olat/selenium/page/core/ContactPage.java  |   9 +-
 .../olat/selenium/page/core/FolderPage.java   |   8 +-
 .../page/core/MenuTreePageFragment.java       |   1 -
 .../course/AssessmentCEConfigurationPage.java |  10 +-
 .../page/course/AssessmentModePage.java       |   8 +-
 .../page/course/CourseEditorPageFragment.java |   6 +-
 .../page/course/CoursePageFragment.java       |   9 +-
 .../page/course/EasyConditionConfigPage.java  |   1 -
 .../EfficiencyStatementConfigurationPage.java |   8 +-
 .../course/EnrollmentConfigurationPage.java   |   9 +-
 .../selenium/page/course/EnrollmentPage.java  |  10 +-
 .../course/GroupTaskConfigurationPage.java    |  10 +-
 .../selenium/page/course/GroupTaskPage.java   |  13 +--
 .../page/course/GroupTaskToCoachPage.java     |   2 -
 .../page/course/InfoMessageCEPage.java        |  12 +-
 .../selenium/page/course/MembersPage.java     |   2 -
 .../selenium/page/course/MyCoursesPage.java   |  10 +-
 .../selenium/page/course/RemindersPage.java   |  10 +-
 .../selenium/page/graphene/OOGraphene.java    |  14 +++
 .../olat/selenium/page/group/GroupsPage.java  |   4 +-
 .../selenium/page/portfolio/BinderPage.java   |   3 -
 .../page/portfolio/BinderPublicationPage.java |   1 -
 .../selenium/page/portfolio/BindersPage.java  |   3 -
 .../selenium/page/portfolio/EntriesPage.java  |   1 -
 .../selenium/page/portfolio/EntryPage.java    |   2 -
 .../selenium/page/qti/QTI21EditorPage.java    |  18 ++-
 .../org/olat/selenium/page/qti/QTI21Page.java |  21 +++-
 .../page/qti/QTI21SectionEditorPage.java      |  88 ++++++++++++++
 .../page/repository/CatalogAdminPage.java     |   9 +-
 .../repository/RepositoryDetailsPage.java     |   9 +-
 .../page/user/EfficiencyStatementPage.java    |   1 -
 .../olat/selenium/page/user/PortalPage.java   |   7 +-
 .../selenium/page/user/UserAdminPage.java     |   2 +
 .../selenium/page/user/UserPasswordPage.java  |  12 +-
 .../user/UserPreferencesPageFragment.java     |  24 ++--
 .../selenium/page/user/UserSettingsPage.java  |  16 +--
 .../org/olat/selenium/page/wiki/WikiPage.java |  14 +--
 45 files changed, 324 insertions(+), 233 deletions(-)
 create mode 100644 src/test/java/org/olat/selenium/page/qti/QTI21SectionEditorPage.java

diff --git a/pom.xml b/pom.xml
index 236cb4c1056..7da11f0ba51 100644
--- a/pom.xml
+++ b/pom.xml
@@ -71,7 +71,7 @@
 		<org.infinispan.version>8.2.5.Final</org.infinispan.version>
 		<lucene.version>4.8.0</lucene.version>
 		<version.selenium>3.4.0</version.selenium>
-		<version.drone>2.1.2</version.drone>
+		<version.drone>2.2.0</version.drone>
 		<activemq.version>5.11.1</activemq.version>
 		<qtiworks.version>1.0.4</qtiworks.version>
 
diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentSectionEditorController.java b/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentSectionEditorController.java
index 09d4254a20d..3289b05ecbb 100644
--- a/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentSectionEditorController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentSectionEditorController.java
@@ -62,6 +62,7 @@ public class AssessmentSectionEditorController extends BasicController {
 		mainVC = createVelocityContainer("assessment_test_editor");
 		mainVC.contextPut("restrictedEdit", restrictedEdit);
 		tabbedPane = new TabbedPane("testTabs", getLocale());
+		tabbedPane.setElementCssClass("o_sel_assessment_section_config");
 		tabbedPane.addListener(this);
 		mainVC.put("tabbedpane", tabbedPane);
 		
diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentSectionExpertOptionsEditorController.java b/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentSectionExpertOptionsEditorController.java
index 341a82d58b3..cccdae8e06e 100644
--- a/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentSectionExpertOptionsEditorController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentSectionExpertOptionsEditorController.java
@@ -53,6 +53,7 @@ public class AssessmentSectionExpertOptionsEditorController extends ItemSessionC
 
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		formLayout.setElementCssClass("o_sel_assessment_section_expert_options");
 		setFormContextHelp("Test editor QTI 2.1 in detail#details_testeditor_section");
 		if(!editable) {
 			setFormWarning("warning.alien.assessment.test");
@@ -67,6 +68,7 @@ public class AssessmentSectionExpertOptionsEditorController extends ItemSessionC
 		//visible
 		String[] yesnoValues = new String[]{ translate("yes"), translate("no") };
 		visibleEl = uifactory.addRadiosHorizontal("visible", "form.section.visible", formLayout, yesnoKeys, yesnoValues);
+		visibleEl.setElementCssClass("o_sel_assessment_section_visible");
 		visibleEl.setEnabled(!restrictedEdit && editable);
 		if (section.getVisible()) {
 			visibleEl.select("y", true);
diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentSectionOptionsEditorController.java b/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentSectionOptionsEditorController.java
index 88e5c422b5b..a38369ed5fb 100644
--- a/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentSectionOptionsEditorController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentSectionOptionsEditorController.java
@@ -77,6 +77,7 @@ public class AssessmentSectionOptionsEditorController extends FormBasicControlle
 
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		formLayout.setElementCssClass("o_sel_assessment_section_options");
 		setFormContextHelp("Test editor QTI 2.1 in detail#details_testeditor_section");
 		if(!editable) {
 			setFormWarning("warning.alien.assessment.test");
diff --git a/src/test/java/org/olat/selenium/ImsQTI21Test.java b/src/test/java/org/olat/selenium/ImsQTI21Test.java
index ce929373d6b..3737fd88e43 100644
--- a/src/test/java/org/olat/selenium/ImsQTI21Test.java
+++ b/src/test/java/org/olat/selenium/ImsQTI21Test.java
@@ -2097,4 +2097,112 @@ public class ImsQTI21Test {
 			.assertOnAssessmentResults()
 			.assertOnDrawing();
 	}
+	
+	/**
+	 * An author make a test with 2 questions and in the expert
+	 * settings of the section, it hides the title. It set the
+	 * access configuration.<br>
+	 * A user search the test, make it, check that the sections
+	 * are not visible, pass the test and check the assessment
+	 * results.
+	 * @param authorLoginPage
+	 * @param participantBrowser
+	 * @throws IOException
+	 * @throws URISyntaxException
+	 */
+	@Test
+	@RunAsClient
+	public void qti21EditorHiddenSection(@InitialPage LoginPage authorLoginPage,
+			@Drone @User WebDriver participantBrowser)
+	throws IOException, URISyntaxException {
+		UserVO author = new UserRestClient(deploymentUrl).createAuthor();
+		UserVO ryomou = new UserRestClient(deploymentUrl).createRandomUser("Ryomou");
+		authorLoginPage.loginAs(author.getLogin(), author.getPassword());
+		
+		String qtiTestTitle = "Choices QTI 2.1 " + UUID.randomUUID();
+		navBar
+			.openAuthoringEnvironment()
+			.createQTI21Test(qtiTestTitle)
+			.clickToolbarBack();
+		
+		QTI21Page qtiPage = QTI21Page
+				.getQTI12Page(browser);
+		QTI21EditorPage qtiEditor = qtiPage
+				.edit();
+		//customize the section
+		qtiEditor
+			.selectSection()
+			.selectExpertOptions()
+			.sectionTitle(false)
+			.save();
+		
+		//edit the default single choice
+		qtiEditor
+			.selectItem("Single Choice");
+		QTI21SingleChoiceEditorPage scEditor = new QTI21SingleChoiceEditorPage(browser);
+		scEditor
+			.setAnswer(0, "Wrong")
+			.addChoice(1)
+			.setCorrect(1)
+			.setAnswer(1, "Correct")
+			.addChoice(2)
+			.setAnswer(2, "Faux")
+			.save();
+		//add a multiple choice
+		QTI21MultipleChoiceEditorPage mcEditor = qtiEditor
+			.addMultipleChoice();
+		mcEditor
+			.setAnswer(0, "Correct")
+			.setCorrect(0)
+			.addChoice(1)
+			.setCorrect(1)
+			.setAnswer(1, "OkToo")
+			.addChoice(2)
+			.setAnswer(2, "Faux")
+			.addChoice(3)
+			.setAnswer(3, "Falsch")
+			.save();
+		qtiPage
+			.clickToolbarBack();
+		// access to all
+		qtiPage
+			.accessConfiguration()
+			.setUserAccess(UserAccess.guest)
+			.clickToolbarBack();
+		// show results
+		qtiPage
+			.options()
+			.showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions())
+			.save();
+		
+		//a user search the content package
+		LoginPage userLoginPage = LoginPage.getLoginPage(participantBrowser, deploymentUrl);
+		userLoginPage
+			.loginAs(ryomou.getLogin(), ryomou.getPassword())
+			.resume();
+		NavigationPage userNavBar = new NavigationPage(participantBrowser);
+		userNavBar
+			.openMyCourses()
+			.openSearch()
+			.extendedSearch(qtiTestTitle)
+			.select(qtiTestTitle)
+			.start();
+		
+		// make the test
+		QTI21Page ryomouQtiPage = QTI21Page
+				.getQTI12Page(participantBrowser);
+		ryomouQtiPage
+			.assertOnAssessmentItem()
+			.assertHiddenSection()
+			.answerSingleChoice("Correct")
+			.saveAnswer()
+			.answerMultipleChoice("OkToo")
+			.answerMultipleChoice("Correct")
+			.saveAnswer()
+			.endTest()
+		//check the results
+			.assertOnAssessmentResults()
+			.assertOnAssessmentTestScore(2)
+			.assertOnAssessmentTestMaxScore(2);
+	}
 }
diff --git a/src/test/java/org/olat/selenium/page/LoginPage.java b/src/test/java/org/olat/selenium/page/LoginPage.java
index b341ea98c3d..f68d323a789 100644
--- a/src/test/java/org/olat/selenium/page/LoginPage.java
+++ b/src/test/java/org/olat/selenium/page/LoginPage.java
@@ -60,9 +60,9 @@ public class LoginPage {
 	@Drone
 	private WebDriver browser;
 	
-	public static LoginPage getLoginPage(WebDriver browser, URL deployemntUrl) {
+	public static LoginPage getLoginPage(WebDriver browser, URL deploymentUrl) {
 		LoginPage page = new LoginPage(browser);
-		browser.navigate().to(deployemntUrl);
+		browser.navigate().to(deploymentUrl);
 		return page;
 	}
 	
@@ -199,7 +199,7 @@ public class LoginPage {
 		OOGraphene.waitBusy(browser);
 		
 		By errorMessageby = By.cssSelector("div.modal-body.alert.alert-danger");
-		OOGraphene.waitElement(errorMessageby, 2, browser);
+		OOGraphene.waitElement(errorMessageby, browser);
 		return this;
 	}
 	
diff --git a/src/test/java/org/olat/selenium/page/NavigationPage.java b/src/test/java/org/olat/selenium/page/NavigationPage.java
index 829ad25fc19..2b17a70d6b3 100644
--- a/src/test/java/org/olat/selenium/page/NavigationPage.java
+++ b/src/test/java/org/olat/selenium/page/NavigationPage.java
@@ -22,7 +22,6 @@ package org.olat.selenium.page;
 import java.util.List;
 
 import org.jboss.arquillian.drone.api.annotation.Drone;
-import org.jboss.arquillian.graphene.Graphene;
 import org.junit.Assert;
 import org.olat.selenium.page.core.AdministrationPage;
 import org.olat.selenium.page.course.MyCoursesPage;
@@ -46,23 +45,22 @@ import org.openqa.selenium.WebElement;
  */
 public class NavigationPage {
 	
-	public static final By toolbarBackBy = By.cssSelector("li.o_breadcrumb_back>a");
-
-	@Drone
-	private WebDriver browser;
-	
-	private By navigationSitesBy = By.cssSelector("ul.o_navbar_sites");
-	private By authoringEnvTabBy = By.cssSelector("li.o_site_author_env > a");
-	private By portalBy = By.cssSelector("li.o_site_portal > a");
-	private By myCoursesBy = By.cssSelector("li.o_site_repository > a");
-	private By userManagementBy = By.cssSelector("li.o_site_useradmin > a");
-	private By administrationBy = By.cssSelector("li.o_site_admin > a");
-	private By catalogBy = By.cssSelector("li.o_site_catalog > a");
-	private By catalogAdministrationBy = By.cssSelector("li.o_site_catalog_admin > a");
-	private	By groupsBy = By.cssSelector("li.o_site_groups > a");
+	private static final By navigationSitesBy = By.cssSelector("ul.o_navbar_sites");
+	private static final By authoringEnvTabBy = By.cssSelector("li.o_site_author_env > a");
+	private static final By portalBy = By.cssSelector("li.o_site_portal > a");
+	private static final By myCoursesBy = By.cssSelector("li.o_site_repository > a");
+	private static final By userManagementBy = By.cssSelector("li.o_site_useradmin > a");
+	private static final By administrationBy = By.cssSelector("li.o_site_admin > a");
+	private static final By catalogBy = By.cssSelector("li.o_site_catalog > a");
+	private static final By catalogAdministrationBy = By.cssSelector("li.o_site_catalog_admin > a");
+	private	static final By groupsBy = By.cssSelector("li.o_site_groups > a");
 	
 	public static final By myCoursesAssertBy = By.xpath("//div[contains(@class,'o_segments')]//a[contains(@onclick,'search.mycourses.student')]");
 	public static final By portalAssertBy = By.className("o_portal");
+	public static final By toolbarBackBy = By.cssSelector("li.o_breadcrumb_back>a");
+	
+	@Drone
+	private WebDriver browser;
 	
 	public NavigationPage() {
 		//
@@ -87,8 +85,7 @@ public class NavigationPage {
 	
 	public PortalPage openPortal() {
 		navigate(portalBy);
-		WebElement main = browser.findElement(By.id("o_main"));
-		return Graphene.createPageFragment(PortalPage.class, main);
+		return new PortalPage(browser);
 	}
 	
 	public MyCoursesPage openMyCourses() {
@@ -131,12 +128,7 @@ public class NavigationPage {
 		}
 
 		OOGraphene.waitElement(linkBy, browser);
-		try {
-			browser.findElement(linkBy).click();
-		} catch (Exception e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
+		browser.findElement(linkBy).click();
 		OOGraphene.waitBusy(browser);
 		OOGraphene.waitingTransition(browser);
 	}
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 7151b7bb006..b210839164b 100644
--- a/src/test/java/org/olat/selenium/page/core/CalendarPage.java
+++ b/src/test/java/org/olat/selenium/page/core/CalendarPage.java
@@ -25,7 +25,6 @@ import java.time.format.DateTimeFormatterBuilder;
 import java.time.temporal.ChronoField;
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.core.util.StringHelper;
 import org.olat.selenium.page.graphene.OOGraphene;
@@ -58,12 +57,7 @@ public class CalendarPage {
 			.appendValue(ChronoField.DAY_OF_MONTH, 2)
 			.toFormatter();
 	
-	@Drone
-	private WebDriver browser;
-	
-	public CalendarPage() {
-		//
-	}
+	private final WebDriver browser;
 	
 	public CalendarPage(WebDriver browser) {
 		this.browser = browser;
@@ -290,8 +284,4 @@ public class CalendarPage {
 		OOGraphene.waitModalDialog(browser);
 		return this;
 	}
-	
-
-	
-
 }
diff --git a/src/test/java/org/olat/selenium/page/core/ContactPage.java b/src/test/java/org/olat/selenium/page/core/ContactPage.java
index 4b842eb1c80..86f8bdf8a31 100644
--- a/src/test/java/org/olat/selenium/page/core/ContactPage.java
+++ b/src/test/java/org/olat/selenium/page/core/ContactPage.java
@@ -21,7 +21,6 @@ package org.olat.selenium.page.core;
 
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebDriver;
@@ -37,12 +36,7 @@ import org.openqa.selenium.WebElement;
  */
 public class ContactPage {
 	
-	@Drone
-	private WebDriver browser;
-	
-	public ContactPage() {
-		//
-	}
+	private final WebDriver browser;
 	
 	public ContactPage(WebDriver browser) {
 		this.browser = browser;
@@ -54,5 +48,4 @@ public class ContactPage {
 		Assert.assertFalse(calendarToolbarsEl.isEmpty());
 		return this;
 	}
-
 }
diff --git a/src/test/java/org/olat/selenium/page/core/FolderPage.java b/src/test/java/org/olat/selenium/page/core/FolderPage.java
index 8627d61f1ae..3ffdfde9b75 100644
--- a/src/test/java/org/olat/selenium/page/core/FolderPage.java
+++ b/src/test/java/org/olat/selenium/page/core/FolderPage.java
@@ -21,7 +21,6 @@ package org.olat.selenium.page.core;
 
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.core.gui.render.URLBuilder;
 import org.olat.selenium.page.graphene.OOGraphene;
@@ -41,12 +40,7 @@ public class FolderPage {
 	
 	public static final By folderBy = By.cssSelector("div.o_briefcase_folder");
 	
-	@Drone
-	private WebDriver browser;
-	
-	public FolderPage() {
-		//
-	}
+	private final WebDriver browser;
 	
 	public FolderPage(WebDriver browser) {
 		this.browser = browser;
diff --git a/src/test/java/org/olat/selenium/page/core/MenuTreePageFragment.java b/src/test/java/org/olat/selenium/page/core/MenuTreePageFragment.java
index 3cd83935bf5..3cac28a2c3b 100644
--- a/src/test/java/org/olat/selenium/page/core/MenuTreePageFragment.java
+++ b/src/test/java/org/olat/selenium/page/core/MenuTreePageFragment.java
@@ -77,7 +77,6 @@ public class MenuTreePageFragment {
 		Assert.assertTrue("Link not found with title: " + title, found);
 		return this;
 	}
-	
 
 	public MenuTreePageFragment assertWithTitle(String title) {
 		boolean found = false;
diff --git a/src/test/java/org/olat/selenium/page/course/AssessmentCEConfigurationPage.java b/src/test/java/org/olat/selenium/page/course/AssessmentCEConfigurationPage.java
index 73da8fdc44c..ec2605e83bc 100644
--- a/src/test/java/org/olat/selenium/page/course/AssessmentCEConfigurationPage.java
+++ b/src/test/java/org/olat/selenium/page/course/AssessmentCEConfigurationPage.java
@@ -21,7 +21,6 @@ package org.olat.selenium.page.course;
 
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
@@ -35,13 +34,8 @@ import org.openqa.selenium.WebElement;
  *
  */
 public class AssessmentCEConfigurationPage {
-	
-	@Drone
-	private WebDriver browser;
-	
-	public AssessmentCEConfigurationPage() {
-		//
-	}
+
+	private final WebDriver browser;
 	
 	public AssessmentCEConfigurationPage(WebDriver browser) {
 		this.browser = browser;
diff --git a/src/test/java/org/olat/selenium/page/course/AssessmentModePage.java b/src/test/java/org/olat/selenium/page/course/AssessmentModePage.java
index 1b53221343a..84d27e375cd 100644
--- a/src/test/java/org/olat/selenium/page/course/AssessmentModePage.java
+++ b/src/test/java/org/olat/selenium/page/course/AssessmentModePage.java
@@ -22,7 +22,6 @@ package org.olat.selenium.page.course;
 import java.util.Date;
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
@@ -40,12 +39,7 @@ import org.openqa.selenium.support.ui.Select;
  */
 public class AssessmentModePage {
 	
-	@Drone
-	private WebDriver browser;
-	
-	public AssessmentModePage() {
-		//
-	}
+	private final WebDriver browser;
 	
 	public AssessmentModePage(WebDriver browser) {
 		this.browser = browser;
diff --git a/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java b/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java
index a1df403d794..34c8b8fccaf 100644
--- a/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java
+++ b/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java
@@ -217,9 +217,7 @@ public class CourseEditorPageFragment {
 	public CourseEditorPageFragment createNode(String nodeAlias) {
 		OOGraphene.waitElement(createNodeButton, 5, browser);
 		browser.findElement(createNodeButton).click();
-		
-		//modal
-		OOGraphene.waitBusyAndScrollTop(browser);
+
 		OOGraphene.waitModalDialog(browser);
 		By node = By.xpath("//div[@id='o_course_editor_choose_nodetype']//a[contains(@class,'o_sel_course_editor_node-" + nodeAlias + "')]");
 		browser.findElement(node).click();
@@ -279,7 +277,6 @@ public class CourseEditorPageFragment {
 		}
 		By changeNodeLinkBy = By.cssSelector("a.o_sel_course_editor_move_node");
 		browser.findElement(changeNodeLinkBy).click();
-		OOGraphene.waitBusyAndScrollTop(browser);
 		OOGraphene.waitModalDialog(browser);
 		
 		By targetNodeBy = By.xpath("//div[contains(@class,'o_tree_insert_tool')]//a[contains(@title,'" + targetNodeTitle + "')]");
@@ -515,7 +512,6 @@ public class CourseEditorPageFragment {
 		//back
 		By breadcrumpBackBy = By.cssSelector("#o_main_toolbar li.o_breadcrumb_back a");
 		browser.findElement(breadcrumpBackBy).click();
-		OOGraphene.waitBusyAndScrollTop(browser);
 		OOGraphene.waitModalDialog(browser);
 		
 		//auto publish
diff --git a/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java b/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java
index 764b5188c5b..049b43233cf 100644
--- a/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java
+++ b/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java
@@ -22,7 +22,6 @@ package org.olat.selenium.page.course;
 import java.net.URL;
 import java.util.List;
 
-import org.jboss.arquillian.graphene.Graphene;
 import org.junit.Assert;
 import org.olat.restapi.support.vo.CourseVO;
 import org.olat.selenium.page.core.BookingPage;
@@ -248,9 +247,7 @@ public class CoursePageFragment {
 		}
 		browser.findElement(assessmentModeBy).click();
 		OOGraphene.waitBusy(browser);
-
-		WebElement main = browser.findElement(By.id("o_main_container"));
-		return Graphene.createPageFragment(AssessmentModePage.class, main);
+		return new AssessmentModePage(browser);
 	}
 	
 	public RepositoryAccessPage accessConfiguration() {
@@ -271,9 +268,7 @@ public class CoursePageFragment {
 		}
 		browser.findElement(efficiencyStatementsBy).click();
 		OOGraphene.waitBusy(browser);
-
-		WebElement main = browser.findElement(By.id("o_main_container"));
-		return Graphene.createPageFragment(EfficiencyStatementConfigurationPage.class, main);
+		return new EfficiencyStatementConfigurationPage(browser);
 	}
 	
 	public BookingPage bookingTool() {
diff --git a/src/test/java/org/olat/selenium/page/course/EasyConditionConfigPage.java b/src/test/java/org/olat/selenium/page/course/EasyConditionConfigPage.java
index 6f9f0dead70..4d17e3e163d 100644
--- a/src/test/java/org/olat/selenium/page/course/EasyConditionConfigPage.java
+++ b/src/test/java/org/olat/selenium/page/course/EasyConditionConfigPage.java
@@ -57,7 +57,6 @@ public class EasyConditionConfigPage {
 		By createBy = By.cssSelector("a.o_sel_condition_create_groups");
 		browser.findElement(createBy).click();
 		OOGraphene.waitModalDialog(browser);
-		OOGraphene.waitBusyAndScrollTop(browser);
 		
 		//fill the form
 		By nameBy = By.cssSelector(".o_sel_group_edit_title input[type='text']");
diff --git a/src/test/java/org/olat/selenium/page/course/EfficiencyStatementConfigurationPage.java b/src/test/java/org/olat/selenium/page/course/EfficiencyStatementConfigurationPage.java
index 183a6ec5e45..e338037c0fc 100644
--- a/src/test/java/org/olat/selenium/page/course/EfficiencyStatementConfigurationPage.java
+++ b/src/test/java/org/olat/selenium/page/course/EfficiencyStatementConfigurationPage.java
@@ -19,7 +19,6 @@
  */
 package org.olat.selenium.page.course;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebDriver;
@@ -32,12 +31,7 @@ import org.openqa.selenium.WebDriver;
  */
 public class EfficiencyStatementConfigurationPage {
 	
-	@Drone
-	private WebDriver browser;
-	
-	public EfficiencyStatementConfigurationPage() {
-		//
-	}
+	private final WebDriver browser;
 	
 	public EfficiencyStatementConfigurationPage(WebDriver browser) {
 		this.browser = browser;
diff --git a/src/test/java/org/olat/selenium/page/course/EnrollmentConfigurationPage.java b/src/test/java/org/olat/selenium/page/course/EnrollmentConfigurationPage.java
index d9996f952aa..6d20b906750 100644
--- a/src/test/java/org/olat/selenium/page/course/EnrollmentConfigurationPage.java
+++ b/src/test/java/org/olat/selenium/page/course/EnrollmentConfigurationPage.java
@@ -21,7 +21,6 @@ package org.olat.selenium.page.course;
 
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
@@ -37,12 +36,7 @@ import org.openqa.selenium.WebElement;
  */
 public class EnrollmentConfigurationPage {
 	
-	@Drone
-	private WebDriver browser;
-	
-	public EnrollmentConfigurationPage() {
-		//
-	}
+	private final WebDriver browser;
 	
 	public EnrollmentConfigurationPage(WebDriver browser) {
 		this.browser = browser;
@@ -83,7 +77,6 @@ public class EnrollmentConfigurationPage {
 		
 		By createGroupBy = By.cssSelector("div.o_button_group_right a");
 		browser.findElement(createGroupBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		
 		//fill the form
diff --git a/src/test/java/org/olat/selenium/page/course/EnrollmentPage.java b/src/test/java/org/olat/selenium/page/course/EnrollmentPage.java
index a95ec02492e..3a722f9cc1d 100644
--- a/src/test/java/org/olat/selenium/page/course/EnrollmentPage.java
+++ b/src/test/java/org/olat/selenium/page/course/EnrollmentPage.java
@@ -21,7 +21,6 @@ package org.olat.selenium.page.course;
 
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
@@ -35,13 +34,8 @@ import org.openqa.selenium.WebElement;
  *
  */
 public class EnrollmentPage {
-	
-	@Drone
-	private WebDriver browser;
-	
-	public EnrollmentPage() {
-		//
-	}
+
+	private final WebDriver browser;
 	
 	public EnrollmentPage(WebDriver browser) {
 		this.browser = browser;
diff --git a/src/test/java/org/olat/selenium/page/course/GroupTaskConfigurationPage.java b/src/test/java/org/olat/selenium/page/course/GroupTaskConfigurationPage.java
index a40e53ece3b..431a015631c 100644
--- a/src/test/java/org/olat/selenium/page/course/GroupTaskConfigurationPage.java
+++ b/src/test/java/org/olat/selenium/page/course/GroupTaskConfigurationPage.java
@@ -22,7 +22,6 @@ package org.olat.selenium.page.course;
 import java.io.File;
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
@@ -38,12 +37,7 @@ import org.openqa.selenium.WebElement;
  */
 public class GroupTaskConfigurationPage {
 
-	@Drone
-	private WebDriver browser;
-	
-	public GroupTaskConfigurationPage() {
-		//
-	}
+	private final WebDriver browser;
 	
 	public GroupTaskConfigurationPage(WebDriver browser) {
 		this.browser = browser;
@@ -64,7 +58,6 @@ public class GroupTaskConfigurationPage {
 	public GroupTaskConfigurationPage openBusinessGroupChooser() {
 		By chooseGroupBy = By.cssSelector("a.o_form_groupchooser");
 		browser.findElement(chooseGroupBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		return this;
 	}
@@ -72,7 +65,6 @@ public class GroupTaskConfigurationPage {
 	public GroupTaskConfigurationPage createBusinessGroup(String name) {
 		By createGroupBy = By.cssSelector("div.o_button_group_right a");
 		browser.findElement(createGroupBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		
 		//fill the form
diff --git a/src/test/java/org/olat/selenium/page/course/GroupTaskPage.java b/src/test/java/org/olat/selenium/page/course/GroupTaskPage.java
index d4ab680132c..f0662777d9f 100644
--- a/src/test/java/org/olat/selenium/page/course/GroupTaskPage.java
+++ b/src/test/java/org/olat/selenium/page/course/GroupTaskPage.java
@@ -22,7 +22,6 @@ package org.olat.selenium.page.course;
 import java.io.File;
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
@@ -38,12 +37,7 @@ import org.openqa.selenium.WebElement;
  */
 public class GroupTaskPage {
 
-	@Drone
-	private WebDriver browser;
-	
-	public GroupTaskPage() {
-		//
-	}
+	private final WebDriver browser;
 	
 	public GroupTaskPage(WebDriver browser) {
 		this.browser = browser;
@@ -99,7 +93,7 @@ public class GroupTaskPage {
 	
 	private GroupTaskPage uploadFile(String stepId, File file) {
 		By uploadButtonBy = By.cssSelector("#" + stepId + " .o_sel_course_gta_submit_file");
-		OOGraphene.clickAndWait(uploadButtonBy, browser);
+		OOGraphene.clickAndWait(uploadButtonBy, browser);//TODO sel clickAndWait
 		OOGraphene.waitModalDialog(browser);
 		
 		By inputBy = By.cssSelector(".o_fileinput input[type='file']");
@@ -114,7 +108,7 @@ public class GroupTaskPage {
 	
 	public GroupTaskPage submitText(String filename, String text) {
 		By uploadButtonBy = By.cssSelector("#o_step_submit_content .o_sel_course_gta_create_doc");
-		OOGraphene.clickAndWait(uploadButtonBy, browser);
+		OOGraphene.clickAndWait(uploadButtonBy, browser);//TODO sel clickAndWait
 		OOGraphene.waitModalDialog(browser);
 		
 		By filenameBy = By.cssSelector(".o_sel_course_gta_doc_filename input[type='text']");
@@ -151,7 +145,6 @@ public class GroupTaskPage {
 	 */
 	private GroupTaskPage confirmDialog() {
 		OOGraphene.waitModalDialog(browser);
-		OOGraphene.waitBusyAndScrollTop(browser);
 		
 		By confirmButtonBy = By.cssSelector("div.modal-dialog div.modal-footer a");
 		browser.findElement(confirmButtonBy).click();
diff --git a/src/test/java/org/olat/selenium/page/course/GroupTaskToCoachPage.java b/src/test/java/org/olat/selenium/page/course/GroupTaskToCoachPage.java
index 42296371ce4..b084083bbbb 100644
--- a/src/test/java/org/olat/selenium/page/course/GroupTaskToCoachPage.java
+++ b/src/test/java/org/olat/selenium/page/course/GroupTaskToCoachPage.java
@@ -105,7 +105,6 @@ public class GroupTaskToCoachPage {
 	}
 	
 	public GroupTaskToCoachPage confirm() {
-		OOGraphene.waitBusyAndScrollTop(browser);
 		OOGraphene.waitModalDialog(browser);
 		WebElement yesLink = browser.findElement(By.xpath("//div[contains(@class,'modal-dialog')]//a[contains(@href,'link_0')]"));
 		yesLink.click();
@@ -174,7 +173,6 @@ public class GroupTaskToCoachPage {
 		} else {
 			buttons.get(0).click();
 		}
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		return this;
 	}
diff --git a/src/test/java/org/olat/selenium/page/course/InfoMessageCEPage.java b/src/test/java/org/olat/selenium/page/course/InfoMessageCEPage.java
index 315b394fa69..a8755eee21e 100644
--- a/src/test/java/org/olat/selenium/page/course/InfoMessageCEPage.java
+++ b/src/test/java/org/olat/selenium/page/course/InfoMessageCEPage.java
@@ -21,7 +21,6 @@ package org.olat.selenium.page.course;
 
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
@@ -36,13 +35,8 @@ import org.openqa.selenium.support.ui.Select;
  *
  */
 public class InfoMessageCEPage {
-	
-	@Drone
-	private WebDriver browser;
-	
-	public InfoMessageCEPage() {
-		//
-	}
+
+	private final WebDriver browser;
 	
 	public InfoMessageCEPage(WebDriver browser) {
 		this.browser = browser;
@@ -56,7 +50,6 @@ public class InfoMessageCEPage {
 	public InfoMessageCEPage createMessage() {
 		By createBy = By.className("o_sel_course_info_create_msg");
 		browser.findElement(createBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		return this;
 	}
@@ -138,7 +131,6 @@ public class InfoMessageCEPage {
 		List<WebElement> editEls = browser.findElements(editBy);
 		Assert.assertFalse(editEls.isEmpty());
 		editEls.get(0).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		return this;
 	}
diff --git a/src/test/java/org/olat/selenium/page/course/MembersPage.java b/src/test/java/org/olat/selenium/page/course/MembersPage.java
index 3b3b3bde24b..13edd6fe77e 100644
--- a/src/test/java/org/olat/selenium/page/course/MembersPage.java
+++ b/src/test/java/org/olat/selenium/page/course/MembersPage.java
@@ -51,7 +51,6 @@ public class MembersPage {
 	public MembersWizardPage addMember() {
 		By addMemberBy = By.className("o_sel_course_add_member");
 		browser.findElement(addMemberBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalWizard(browser);
 		OOGraphene.waitElement(By.cssSelector("fieldset.o_sel_usersearch_searchform"), 5, browser);
 		return new MembersWizardPage(browser);
@@ -60,7 +59,6 @@ public class MembersPage {
 	public MembersWizardPage importMembers() {
 		By importMembersBy = By.className("o_sel_course_import_members");
 		browser.findElement(importMembersBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalWizard(browser);
 		OOGraphene.waitElement(By.cssSelector("div.o_sel_user_import textarea.form-control"), 5, browser);
 		return new MembersWizardPage(browser);
diff --git a/src/test/java/org/olat/selenium/page/course/MyCoursesPage.java b/src/test/java/org/olat/selenium/page/course/MyCoursesPage.java
index 21ccff896cc..66047e24401 100644
--- a/src/test/java/org/olat/selenium/page/course/MyCoursesPage.java
+++ b/src/test/java/org/olat/selenium/page/course/MyCoursesPage.java
@@ -21,7 +21,6 @@ package org.olat.selenium.page.course;
 
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
@@ -36,13 +35,8 @@ import org.openqa.selenium.WebElement;
  *
  */
 public class MyCoursesPage {
-	
-	@Drone
-	private WebDriver browser;
-	
-	public MyCoursesPage() {
-		//
-	}
+
+	private final WebDriver browser;
 	
 	public MyCoursesPage(WebDriver browser) {
 		this.browser = browser;
diff --git a/src/test/java/org/olat/selenium/page/course/RemindersPage.java b/src/test/java/org/olat/selenium/page/course/RemindersPage.java
index 1c78ead8fb9..7d643ff547c 100644
--- a/src/test/java/org/olat/selenium/page/course/RemindersPage.java
+++ b/src/test/java/org/olat/selenium/page/course/RemindersPage.java
@@ -21,7 +21,6 @@ package org.olat.selenium.page.course;
 
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.selenium.page.NavigationPage;
 import org.olat.selenium.page.graphene.OOGraphene;
@@ -38,13 +37,8 @@ import org.openqa.selenium.support.ui.Select;
  *
  */
 public class RemindersPage {
-	
-	@Drone
-	private WebDriver browser;
-	
-	public RemindersPage() {
-		//
-	}
+
+	private final WebDriver browser;
 	
 	public RemindersPage(WebDriver browser) {
 		this.browser = browser;
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 8eeb4205a18..5c38802b58f 100644
--- a/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java
+++ b/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java
@@ -54,13 +54,27 @@ public class OOGraphene {
 	public static final By wizardNextBy = By.xpath("//div[contains(@class,'modal-footer')]//a[contains(@class,'o_wizard_button_next')]");
 	public static final By wizardFinishBy = By.xpath("//div[contains(@class,'modal-footer')]//a[contains(@class,'o_wizard_button_finish') and not(contains(@class,'o_disabled'))]");
 	
+	/**
+	 * Wait until the busy flag is ok, the browser scrolled
+	 * to the top and that the body of the modal dialog is visible.
+	 * 
+	 * @param The browser
+	 */
 	public static void waitModalDialog(WebDriver browser) {
+		waitBusyAndScrollTop(browser);
 		By modalBy = By.cssSelector("div.modal-dialog div.modal-body");
 		Graphene.waitModel(browser).withTimeout(5, TimeUnit.SECONDS)
 			.pollingEvery(200, TimeUnit.MILLISECONDS).until().element(modalBy).is().visible();
 	}
 	
+	/**
+	 * Wait until the busy flag is ok, the browser scrolled
+	 * to the top and that the body of the modal dialog is visible.
+	 * 
+	 * @param The browser
+	 */
 	public static void waitModalWizard(WebDriver browser) {
+		waitBusyAndScrollTop(browser);
 		By modalBy = By.cssSelector("div.modal-dialog div.modal-body");
 		Graphene.waitModel(browser).withTimeout(defaultTimeout, TimeUnit.SECONDS)
 			.pollingEvery(200, TimeUnit.MILLISECONDS).until().element(modalBy).is().visible();
diff --git a/src/test/java/org/olat/selenium/page/group/GroupsPage.java b/src/test/java/org/olat/selenium/page/group/GroupsPage.java
index 3e0b0be9d43..0c0af063f18 100644
--- a/src/test/java/org/olat/selenium/page/group/GroupsPage.java
+++ b/src/test/java/org/olat/selenium/page/group/GroupsPage.java
@@ -66,9 +66,7 @@ public class GroupsPage {
 	public GroupPage createGroup(String name, String description) {
 		//click create button
 		By createBy = By.className("o_sel_group_create");
-		WebElement createButton = browser.findElement(createBy);
-		createButton.click();
-		OOGraphene.waitBusy(browser);
+		browser.findElement(createBy).click();
 		OOGraphene.waitModalDialog(browser);
 		By popupBy = By.cssSelector("div.modal-content fieldset.o_sel_group_edit_group_form");
 		OOGraphene.waitElement(popupBy, 5, browser);
diff --git a/src/test/java/org/olat/selenium/page/portfolio/BinderPage.java b/src/test/java/org/olat/selenium/page/portfolio/BinderPage.java
index ec5df8d6b5f..048900cfc9d 100644
--- a/src/test/java/org/olat/selenium/page/portfolio/BinderPage.java
+++ b/src/test/java/org/olat/selenium/page/portfolio/BinderPage.java
@@ -230,7 +230,6 @@ public class BinderPage {
 		//click create button
 		By createBy = By.className("o_sel_pf_new_section");
 		browser.findElement(createBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		By popupBy = By.cssSelector("div.modal-content fieldset.o_sel_pf_edit_section_form");
 		OOGraphene.waitElement(popupBy, 5, browser);
@@ -257,7 +256,6 @@ public class BinderPage {
 		By createBy = By.className("o_sel_pf_new_entry");
 		WebElement createButton = browser.findElement(createBy);
 		createButton.click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		By popupBy = By.cssSelector("div.modal-content fieldset.o_sel_pf_edit_entry_form");
 		OOGraphene.waitElement(popupBy, 5, browser);
@@ -287,7 +285,6 @@ public class BinderPage {
 		Assert.assertEquals(1, newAssignmentButtons.size());
 		newAssignmentButtons.get(0).click();
 		
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		By popupBy = By.cssSelector("div.modal-content fieldset.o_sel_pf_edit_assignment_form");
 		OOGraphene.waitElement(popupBy, 5, browser);
diff --git a/src/test/java/org/olat/selenium/page/portfolio/BinderPublicationPage.java b/src/test/java/org/olat/selenium/page/portfolio/BinderPublicationPage.java
index 61cc9523f54..ad27c7922ed 100644
--- a/src/test/java/org/olat/selenium/page/portfolio/BinderPublicationPage.java
+++ b/src/test/java/org/olat/selenium/page/portfolio/BinderPublicationPage.java
@@ -49,7 +49,6 @@ public class BinderPublicationPage {
 	public BinderMemberWizardPage addMember() {
 		By memberBy = By.cssSelector("a.o_sel_pf_access_member");
 		browser.findElement(memberBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		return new BinderMemberWizardPage(browser);
 	}
diff --git a/src/test/java/org/olat/selenium/page/portfolio/BindersPage.java b/src/test/java/org/olat/selenium/page/portfolio/BindersPage.java
index 69b0dc310d2..826382b8b0b 100644
--- a/src/test/java/org/olat/selenium/page/portfolio/BindersPage.java
+++ b/src/test/java/org/olat/selenium/page/portfolio/BindersPage.java
@@ -41,11 +41,8 @@ public class BindersPage {
 	public BinderPage createBinder(String title, String summary) {
 		By newBinderBy = By.cssSelector("li.o_tool a.o_sel_pf_new_binder");
 		browser.findElement(newBinderBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		
-		OOGraphene.waitBusy(browser);
-		OOGraphene.waitModalDialog(browser);
 		By popupBy = By.cssSelector("div.modal-content fieldset.o_sel_pf_edit_binder_form");
 		OOGraphene.waitElement(popupBy, 5, browser);
 		
diff --git a/src/test/java/org/olat/selenium/page/portfolio/EntriesPage.java b/src/test/java/org/olat/selenium/page/portfolio/EntriesPage.java
index b6b554328fd..5f24e70d75f 100644
--- a/src/test/java/org/olat/selenium/page/portfolio/EntriesPage.java
+++ b/src/test/java/org/olat/selenium/page/portfolio/EntriesPage.java
@@ -47,7 +47,6 @@ public class EntriesPage {
 		By createBy = By.className("o_sel_pf_new_entry");
 		WebElement createButton = browser.findElement(createBy);
 		createButton.click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		By popupBy = By.cssSelector("div.modal-content fieldset.o_sel_pf_edit_entry_form");
 		OOGraphene.waitElement(popupBy, 5, browser);
diff --git a/src/test/java/org/olat/selenium/page/portfolio/EntryPage.java b/src/test/java/org/olat/selenium/page/portfolio/EntryPage.java
index 6ea7a5d2755..171fdbda04f 100644
--- a/src/test/java/org/olat/selenium/page/portfolio/EntryPage.java
+++ b/src/test/java/org/olat/selenium/page/portfolio/EntryPage.java
@@ -178,7 +178,6 @@ public class EntryPage {
 		By moveToTrashBy = By.cssSelector("a.o_sel_pf_move_page_to_trash");
 		OOGraphene.waitElement(moveToTrashBy, 5, browser);
 		browser.findElement(moveToTrashBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		
 		BinderPage binder = new BinderPage(browser);
@@ -190,7 +189,6 @@ public class EntryPage {
 		By moveToTrashBy = By.cssSelector("a.o_sel_pf_delete_page");
 		OOGraphene.waitElement(moveToTrashBy, 5, browser);
 		browser.findElement(moveToTrashBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		
 		new BinderPage(browser).confirm();
diff --git a/src/test/java/org/olat/selenium/page/qti/QTI21EditorPage.java b/src/test/java/org/olat/selenium/page/qti/QTI21EditorPage.java
index 5508ecb30fc..922e0f27244 100644
--- a/src/test/java/org/olat/selenium/page/qti/QTI21EditorPage.java
+++ b/src/test/java/org/olat/selenium/page/qti/QTI21EditorPage.java
@@ -54,7 +54,6 @@ public class QTI21EditorPage {
 		
 		By importBy = By.xpath("//ul[contains(@class,'o_sel_qti_elements')]//a[contains(@onclick,'import.table')]");
 		browser.findElement(importBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		return new QTI21CSVImportWizard(browser);
 	}
@@ -66,17 +65,32 @@ public class QTI21EditorPage {
 		return this;
 	}
 	
+	public QTI21SectionEditorPage selectSection() {
+		By firstSectionBy = By.xpath("//div[contains(@class,'o_assessment_test_editor_menu')]//a[i[contains(@class,'o_mi_qtisection')]]");
+		browser.findElement(firstSectionBy).click();
+		OOGraphene.waitBusy(browser);
+		OOGraphene.waitElement(By.className("o_sel_assessment_section_options"), browser);
+		return new QTI21SectionEditorPage(browser);
+	}
+	
 	public QTI21EditorPage selectNode(String title) {
 		menuTree.selectWithTitle(title);
 		return this;
 	}
 	
+	public QTI21EditorPage selectItem(String title) {
+		By itemBy = By.xpath("//li/div/span[contains(@class,'o_tree_level_label_leaf')]/a[span[contains(text(),'" + title + "')]]");
+		OOGraphene.waitElement(itemBy, browser);
+		browser.findElement(itemBy).click();
+		OOGraphene.waitBusyAndScrollTop(browser);
+		return this;
+	}
+	
 	public QTI21EditorPage deleteNode() {
 		openChangeMenu();
 		
 		By importBy = By.xpath("//ul[contains(@class,'o_sel_qti_change_node')]//a[contains(@onclick,'tools.delete')]");
 		browser.findElement(importBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		
 		confirm();
diff --git a/src/test/java/org/olat/selenium/page/qti/QTI21Page.java b/src/test/java/org/olat/selenium/page/qti/QTI21Page.java
index 54f7ca6d059..b553cd5162e 100644
--- a/src/test/java/org/olat/selenium/page/qti/QTI21Page.java
+++ b/src/test/java/org/olat/selenium/page/qti/QTI21Page.java
@@ -332,6 +332,13 @@ public class QTI21Page {
 		return this;
 	}
 	
+	public QTI21Page assertHiddenSection() {
+		By sectionBy = By.cssSelector("li.o_assessmentsection.o_qti_menu_item>header>h4");
+		List<WebElement> sectionEls = browser.findElements(sectionBy);
+		Assert.assertEquals(0, sectionEls.size());
+		return this;
+	}
+	
 	/**
 	 * This check specifically if the metadata of the test are visible.
 	 * 
@@ -339,7 +346,17 @@ public class QTI21Page {
 	 */
 	public QTI21Page assertOnAssessmentResults() {
 		By resultsBy = By.cssSelector("div.o_sel_results_details");
-		OOGraphene.waitElement(resultsBy, 5, browser);
+		OOGraphene.waitElement(resultsBy, browser);
+		return this;
+	}
+	
+	public QTI21Page assertOnAssessmentTestResults() {
+		try {
+			By resultsBy = By.cssSelector("div.o_sel_results_details");
+			OOGraphene.waitElement(resultsBy, browser);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
 		return this;
 	}
 	
@@ -347,7 +364,7 @@ public class QTI21Page {
 	 * This check specifically if the metadata of the test are visible.
 	 * 
 	 * @param timeout
-	 * @return
+	 * @return Itself
 	 */
 	public QTI21Page assertOnAssessmentResults(int timeout) {
 		By resultsBy = By.cssSelector("div.o_sel_results_details");
diff --git a/src/test/java/org/olat/selenium/page/qti/QTI21SectionEditorPage.java b/src/test/java/org/olat/selenium/page/qti/QTI21SectionEditorPage.java
new file mode 100644
index 00000000000..e2b086176bf
--- /dev/null
+++ b/src/test/java/org/olat/selenium/page/qti/QTI21SectionEditorPage.java
@@ -0,0 +1,88 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.selenium.page.qti;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.olat.selenium.page.graphene.OOGraphene;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+
+/**
+ * 
+ * Initial date: 26 juin 2017<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class QTI21SectionEditorPage {
+	
+	public static final By tabBarBy = By.cssSelector("ul.o_sel_assessment_section_config>li>a");
+	
+	private final WebDriver browser;
+	
+	public QTI21SectionEditorPage(WebDriver browser) {
+		this.browser = browser;
+	}
+	
+	public QTI21SectionEditorPage selectExpertOptions() {
+		By expertTabBy = By.cssSelector("fieldset.o_sel_assessment_section_expert_options");
+		return selectTab(expertTabBy);
+	}
+	
+	public QTI21SectionEditorPage sectionTitle(boolean visible) {
+		By radioBy;
+		if(visible) {
+			radioBy = By.xpath("//div[contains(@class,'o_sel_assessment_section_visible')]//input[@type='radio'][@name='visible'][@value='y']");
+		} else {
+			radioBy = By.xpath("//div[contains(@class,'o_sel_assessment_section_visible')]//input[@type='radio'][@name='visible'][@value='n']");
+		}
+		browser.findElement(radioBy).click();
+		return this;
+	}
+	
+	public QTI21SectionEditorPage save() {
+		By saveBy = By.cssSelector("fieldset.o_sel_assessment_section_expert_options button.btn-primary");
+		browser.findElement(saveBy).click();
+		OOGraphene.waitBusy(browser);
+		return this;
+	}
+	
+	protected QTI21SectionEditorPage selectTab(By tabBy) {
+		List<WebElement> tabLinks = browser.findElements(tabBarBy);
+
+		boolean found = false;
+		a_a:
+		for(WebElement tabLink:tabLinks) {
+			tabLink.click();
+			OOGraphene.waitBusy(browser);
+			List<WebElement> tabEls = browser.findElements(tabBy);
+			if(tabEls.size() > 0) {
+				found = true;
+				break a_a;
+			}
+		}
+
+		Assert.assertTrue("Found the tab", found);
+		return this;
+	}
+
+}
diff --git a/src/test/java/org/olat/selenium/page/repository/CatalogAdminPage.java b/src/test/java/org/olat/selenium/page/repository/CatalogAdminPage.java
index c19c97dadb9..bc203b3ec02 100644
--- a/src/test/java/org/olat/selenium/page/repository/CatalogAdminPage.java
+++ b/src/test/java/org/olat/selenium/page/repository/CatalogAdminPage.java
@@ -21,7 +21,6 @@ package org.olat.selenium.page.repository;
 
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
@@ -37,12 +36,7 @@ import org.openqa.selenium.WebElement;
  */
 public class CatalogAdminPage {
 	
-	@Drone
-	private WebDriver browser;
-	
-	public CatalogAdminPage() {
-		//
-	}
+	private final WebDriver browser;
 	
 	public CatalogAdminPage(WebDriver browser) {
 		this.browser = browser;
@@ -59,7 +53,6 @@ public class CatalogAdminPage {
 		//click in toolbox
 		By addNodeBy = By.className("o_sel_catalog_add_category");
 		browser.findElement(addNodeBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		
 		//fill the form
diff --git a/src/test/java/org/olat/selenium/page/repository/RepositoryDetailsPage.java b/src/test/java/org/olat/selenium/page/repository/RepositoryDetailsPage.java
index 92f683c2161..7de8f8daf4d 100644
--- a/src/test/java/org/olat/selenium/page/repository/RepositoryDetailsPage.java
+++ b/src/test/java/org/olat/selenium/page/repository/RepositoryDetailsPage.java
@@ -21,7 +21,6 @@ package org.olat.selenium.page.repository;
 
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
@@ -41,9 +40,11 @@ public class RepositoryDetailsPage {
 	public static final By launchBy = By.className("o_sel_author_launch");
 	public static final By editBy = By.className("o_sel_author_edit_entry");
 	
-
-	@Drone
-	private WebDriver browser;
+	private final WebDriver browser;
+	
+	public RepositoryDetailsPage(WebDriver browser) {
+		this.browser = browser;
+	}
 	
 	public RepositoryDetailsPage assertOnTitle(String displayName) {
 		List<WebElement> titleList = browser.findElements(By.tagName("h1"));
diff --git a/src/test/java/org/olat/selenium/page/user/EfficiencyStatementPage.java b/src/test/java/org/olat/selenium/page/user/EfficiencyStatementPage.java
index b2342e0c9e7..fa31d0d3d33 100644
--- a/src/test/java/org/olat/selenium/page/user/EfficiencyStatementPage.java
+++ b/src/test/java/org/olat/selenium/page/user/EfficiencyStatementPage.java
@@ -182,7 +182,6 @@ public class EfficiencyStatementPage {
 		By collectBy = By.xpath("//div[contains(@class,'o_sel_certificates_table')]//table//tr[td[contains(text(),'" + courseTitle + "')]]/td/a[contains(@href,'cmd.MEDIA')]");
 		OOGraphene.waitElement(collectBy, 5, browser);
 		browser.findElement(collectBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		return new MediaPage(browser);
 	}
diff --git a/src/test/java/org/olat/selenium/page/user/PortalPage.java b/src/test/java/org/olat/selenium/page/user/PortalPage.java
index 16de31375b3..4d42b18c2ad 100644
--- a/src/test/java/org/olat/selenium/page/user/PortalPage.java
+++ b/src/test/java/org/olat/selenium/page/user/PortalPage.java
@@ -21,7 +21,6 @@ package org.olat.selenium.page.user;
 
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
@@ -49,9 +48,11 @@ public class PortalPage {
 	private static final By moveUpBy = By.className("o_portlet_edit_up");
 	private static final By moveDownBy = By.className("o_portlet_edit_down");
 	
-	@Drone
-	private WebDriver browser;
+	private final WebDriver browser;
 	
+	public PortalPage(WebDriver browser) {
+		this.browser = browser;
+	}
 	
 	public PortalPage edit() {
 		By editBy = By.cssSelector(".o_home_portaleditlink a.btn-default");
diff --git a/src/test/java/org/olat/selenium/page/user/UserAdminPage.java b/src/test/java/org/olat/selenium/page/user/UserAdminPage.java
index 160a7685df9..a7456fc0064 100644
--- a/src/test/java/org/olat/selenium/page/user/UserAdminPage.java
+++ b/src/test/java/org/olat/selenium/page/user/UserAdminPage.java
@@ -106,11 +106,13 @@ public class UserAdminPage {
 	public UserAdminPage selectAndDeleteUser(String lastName) {
 		By checkBy = By.cssSelector("fieldset.o_sel_usersearch_searchform table input[type='checkbox']");
 		browser.findElement(checkBy).click();
+		OOGraphene.waitBusy(browser);
 		
 		//select
 		By selectBy = By.cssSelector("fieldset.o_sel_usersearch_searchform div.o_table_wrapper div.o_table_buttons button.btn.btn-default");
 		browser.findElement(selectBy).click();
 		OOGraphene.waitBusy(browser);
+		OOGraphene.waitModalDialog(browser);
 		
 		//confirm
 		By usernameBy = By.xpath("//div[contains(@class,'modal-dialog')]//p[text()[contains(.,'" + lastName + "')]]");
diff --git a/src/test/java/org/olat/selenium/page/user/UserPasswordPage.java b/src/test/java/org/olat/selenium/page/user/UserPasswordPage.java
index e0d2b86bd75..42e8131226c 100644
--- a/src/test/java/org/olat/selenium/page/user/UserPasswordPage.java
+++ b/src/test/java/org/olat/selenium/page/user/UserPasswordPage.java
@@ -19,8 +19,6 @@
  */
 package org.olat.selenium.page.user;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
-import org.jboss.arquillian.graphene.Graphene;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebDriver;
@@ -38,13 +36,15 @@ public class UserPasswordPage {
 
 	public static final By oldPasswordBy = By.className("o_sel_home_pwd_old");
 	
-	@Drone
-	private WebDriver browser;
+	private final WebDriver browser;
+	
+	private UserPasswordPage(WebDriver browser) {
+		this.browser = browser;
+	}
 	
 	public static UserPasswordPage getUserPasswordPage(WebDriver browser) {
 		OOGraphene.waitElement(oldPasswordBy, browser);
-		WebElement main = browser.findElement(By.id("o_main"));
-		return Graphene.createPageFragment(UserPasswordPage.class, main);
+		return new UserPasswordPage(browser);
 	}
 	
 	public UserPasswordPage setNewPassword(String oldPassword, String newPassword) {
diff --git a/src/test/java/org/olat/selenium/page/user/UserPreferencesPageFragment.java b/src/test/java/org/olat/selenium/page/user/UserPreferencesPageFragment.java
index 45c187b8050..e154c5cb3bf 100644
--- a/src/test/java/org/olat/selenium/page/user/UserPreferencesPageFragment.java
+++ b/src/test/java/org/olat/selenium/page/user/UserPreferencesPageFragment.java
@@ -21,14 +21,12 @@ package org.olat.selenium.page.user;
 
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.junit.Assert;
 import org.olat.selenium.page.LoginPage;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
-import org.openqa.selenium.support.FindBy;
 import org.openqa.selenium.support.ui.Select;
 
 /**
@@ -48,28 +46,22 @@ public class UserPreferencesPageFragment {
 	public static final By saveSystemPrefsButton = By.xpath("//div[contains(@class,'o_sel_home_settings_prefs_buttons')]//button[@type='button']");
 	public static final By resetPrefsButton = By.xpath("//div[contains(@class,'o_sel_home_settings_reset_sysprefs_buttons')]//button[@type='button']");
 	
+	private static final By resumeFieldsetBy = By.className("o_sel_home_settings_resume");
 	
+	private final WebDriver browser;
 	
-	@Drone
-	private WebDriver browser;
-	
-	@FindBy(className = "o_sel_home_settings_resume")
-	private WebElement resumeFieldset;
-	
-	/**
-	 * @return True if the user's preference panel is displayed.
-	 */
-	public boolean isDisplayed() {
-		return resumeFieldset.isDisplayed();
+	public UserPreferencesPageFragment(WebDriver browser) {
+		this.browser = browser;
 	}
-	
+
 	/**
 	 * Check that the user preferences page is displayed.
 	 * 
 	 * @return The user preferences page fragment
 	 */
 	public UserPreferencesPageFragment assertOnUserPreferences() {
-		Assert.assertTrue(resumeFieldset.isDisplayed());
+		OOGraphene.waitElement(resumeFieldsetBy, browser);
+		Assert.assertTrue(browser.findElement(resumeFieldsetBy).isDisplayed());
 		return this;
 	}
 	
@@ -80,7 +72,7 @@ public class UserPreferencesPageFragment {
 	 * @return
 	 */
 	public UserPreferencesPageFragment setResume(ResumeOption resume) {
-		Assert.assertTrue(resumeFieldset.isDisplayed());
+		OOGraphene.waitElement(resumeFieldsetBy, browser);
 		WebElement radio = null;
 		switch(resume) {
 			case none: radio = browser.findElement(noneRadio); break;
diff --git a/src/test/java/org/olat/selenium/page/user/UserSettingsPage.java b/src/test/java/org/olat/selenium/page/user/UserSettingsPage.java
index d7be3340f81..588c8ea7102 100644
--- a/src/test/java/org/olat/selenium/page/user/UserSettingsPage.java
+++ b/src/test/java/org/olat/selenium/page/user/UserSettingsPage.java
@@ -19,8 +19,6 @@
  */
 package org.olat.selenium.page.user;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
-import org.jboss.arquillian.graphene.Graphene;
 import org.junit.Assert;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.openqa.selenium.By;
@@ -35,12 +33,7 @@ import org.openqa.selenium.WebElement;
  */
 public class UserSettingsPage {
 
-	@Drone
-	private WebDriver browser;
-	
-	public UserSettingsPage() {
-		//
-	}
+	private final WebDriver browser;
 	
 	public UserSettingsPage(WebDriver browser) {
 		this.browser = browser;
@@ -63,11 +56,8 @@ public class UserSettingsPage {
 	 */
 	public UserPreferencesPageFragment openPreferences() {
 		By preferencesSegmentBy = By.className("o_sel_user_settings_prefs");
-		WebElement preferencesSegmentLink = browser.findElement(preferencesSegmentBy);
-		preferencesSegmentLink.click();
+		browser.findElement(preferencesSegmentBy).click();
 		OOGraphene.waitBusy(browser);
-
-		WebElement main = browser.findElement(By.id("o_main"));
-		return Graphene.createPageFragment(UserPreferencesPageFragment.class, main);
+		return new UserPreferencesPageFragment(browser);
 	}
 }
diff --git a/src/test/java/org/olat/selenium/page/wiki/WikiPage.java b/src/test/java/org/olat/selenium/page/wiki/WikiPage.java
index 42a16a8dafa..33678e7a0db 100644
--- a/src/test/java/org/olat/selenium/page/wiki/WikiPage.java
+++ b/src/test/java/org/olat/selenium/page/wiki/WikiPage.java
@@ -21,8 +21,6 @@ package org.olat.selenium.page.wiki;
 
 import java.util.List;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
-import org.jboss.arquillian.graphene.Graphene;
 import org.junit.Assert;
 import org.olat.selenium.page.graphene.OOGraphene;
 import org.olat.selenium.page.portfolio.MediaPage;
@@ -42,20 +40,15 @@ public class WikiPage {
 	
 	public static final By wikiWrapperBy = By.cssSelector("div.o_wiki_wrapper");
 	
-	@Drone
-	private WebDriver browser;
-	
-	public WikiPage() {
-		//
-	}
+	private final WebDriver browser;
 	
 	public WikiPage(WebDriver browser) {
 		this.browser = browser;
 	}
 	
 	public static WikiPage getWiki(WebDriver browser) {
-		WebElement main = browser.findElement(By.id("o_main_wrapper"));
-		return Graphene.createPageFragment(WikiPage.class, main);
+		OOGraphene.waitElement(By.id("o_main_wrapper"), browser);
+		return new WikiPage(browser);
 	}
 	
 	public static WikiPage getGroupWiki(WebDriver browser) {
@@ -130,7 +123,6 @@ public class WikiPage {
 		By collectBy = By.cssSelector(".o_wikimod_nav .o_portfolio_collector");
 		OOGraphene.waitElement(collectBy, 5, browser);
 		browser.findElement(collectBy).click();
-		OOGraphene.waitBusy(browser);
 		OOGraphene.waitModalDialog(browser);
 		return new MediaPage(browser);
 	}
-- 
GitLab