From 4a3e3a20b76345514405f388fa8827da12e1d46e Mon Sep 17 00:00:00 2001
From: srosse <stephane.rosse@frentix.com>
Date: Thu, 23 Jul 2020 21:28:53 +0200
Subject: [PATCH] no-jira: selenium test for course element checklist

---
 .../cl/ui/CheckListBoxListEditController.java |   8 +-
 .../ui/CheckListConfigurationController.java  |   4 +
 .../nodes/cl/ui/CheckboxEditController.java   |   4 +
 .../org/olat/selenium/CourseElementTest.java  | 111 ++++++++++++++++++
 .../page/course/CheckListConfigPage.java      | 109 +++++++++++++++++
 .../selenium/page/course/CheckListPage.java   |  53 +++++++++
 6 files changed, 286 insertions(+), 3 deletions(-)
 create mode 100644 src/test/java/org/olat/selenium/page/course/CheckListConfigPage.java
 create mode 100644 src/test/java/org/olat/selenium/page/course/CheckListPage.java

diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListBoxListEditController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListBoxListEditController.java
index 51e90f0eb07..e5e723d2736 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListBoxListEditController.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListBoxListEditController.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
-import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.form.flexible.FormItem;
@@ -59,6 +58,7 @@ import org.olat.course.nodes.cl.model.CheckboxList;
 import org.olat.course.nodes.cl.ui.CheckboxConfigDataModel.Cols;
 import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.modules.ModuleConfiguration;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * Controller to manage a list of checks
@@ -83,7 +83,8 @@ public class CheckListBoxListEditController extends FormBasicController {
 	private final CourseEnvironment courseEnv;
 	private final CheckListCourseNode courseNode;
 
-	private final CheckboxManager checkboxManager;
+	@Autowired
+	private CheckboxManager checkboxManager;
 	
 	public CheckListBoxListEditController(UserRequest ureq, WindowControl wControl,
 			OLATResourceable courseOres, CheckListCourseNode courseNode, boolean inUse) {
@@ -95,7 +96,6 @@ public class CheckListBoxListEditController extends FormBasicController {
 		ICourse course = CourseFactory.loadCourse(courseOres);
 		courseEnv = course.getCourseEnvironment();
 		config = courseNode.getModuleConfiguration();
-		checkboxManager = CoreSpringFactory.getImpl(CheckboxManager.class);
 		
 		initForm(ureq);
 	}
@@ -105,6 +105,7 @@ public class CheckListBoxListEditController extends FormBasicController {
 		setFormTitle("config.checkbox.title");
 		setFormDescription("config.checkbox.description");
 		setFormContextHelp("Assessment#_checklist_cb");
+		formLayout.setElementCssClass("o_sel_cl_edit_checklist");
 		if(inUse) {
 			setFormWarning("config.warning.inuse");
 		}
@@ -114,6 +115,7 @@ public class CheckListBoxListEditController extends FormBasicController {
 		formLayout.add(tableCont);
 		
 		addLink = uifactory.addFormLink("add.checkbox", tableCont, Link.BUTTON);
+		addLink.setElementCssClass("o_sel_cl_new_checkbox");
 		
 		FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.title.i18nKey(), Cols.title.ordinal()));
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListConfigurationController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListConfigurationController.java
index 039b6e1def3..eb751f1990f 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListConfigurationController.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListConfigurationController.java
@@ -101,6 +101,7 @@ public class CheckListConfigurationController extends FormBasicController {
 	
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		formLayout.setElementCssClass("o_sel_cl_edit_assessment");
 		if(wizard) {
 			titlePrefixEl = uifactory.addTextElement("titelprefix", "title.prefix", 64, "", formLayout);
 			titlePrefixEl.setMandatory(true);
@@ -151,10 +152,12 @@ public class CheckListConfigurationController extends FormBasicController {
 		}
 		String minValStr = minVal == null ? "" : Float.toString(minVal.floatValue());
 		minPointsEl = uifactory.addTextElement("pointsmin", "config.points.min", 4, minValStr, formLayout);
+		minPointsEl.setElementCssClass("o_sel_cl_min_score");
 		minPointsEl.setMandatory(true);
 		minPointsEl.setDisplaySize(5);
 		String maxValStr = maxVal == null ? "" : Float.toString(maxVal.floatValue());
 		maxPointsEl = uifactory.addTextElement("pointsmax", "config.points.max", 4, maxValStr, formLayout);
+		maxPointsEl.setElementCssClass("o_sel_cl_max_score");
 		maxPointsEl.setMandatory(true);
 		maxPointsEl.setDisplaySize(5);
 		
@@ -180,6 +183,7 @@ public class CheckListConfigurationController extends FormBasicController {
 		
 		String cutValStr = cutVal == null ? "" : Float.toString(cutVal.floatValue());
 		cutValueEl = uifactory.addTextElement("cutvalue", "config.cutvalue", 4, cutValStr, formLayout);
+		cutValueEl.setElementCssClass("o_sel_cl_cut_value");
 		cutValueEl.setDisplaySize(5);
 		cutValueEl.setMandatory(true);
 		
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxEditController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxEditController.java
index 35e9beaf9b4..b2ae96d03a7 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxEditController.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxEditController.java
@@ -114,8 +114,10 @@ public class CheckboxEditController extends FormBasicController {
 
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		formLayout.setElementCssClass("o_sel_cl_edit_checkbox_form");
 		String title = checkbox.getTitle();
 		titleEl = uifactory.addTextElement("checkbox.title", "checkbox.title", 255, title, formLayout);
+		titleEl.setElementCssClass("o_sel_cl_checkbox_title");
 		
 		String[] releaseKeys = new String[] {
 				CheckboxReleaseEnum.userAndCoach.name(), CheckboxReleaseEnum.coachOnly.name()
@@ -142,6 +144,7 @@ public class CheckboxEditController extends FormBasicController {
 		String[] onKeys = new String[] { "on" };
 		String[] onValues = new String[] { translate("award.point.on") };
 		awardPointEl = uifactory.addCheckboxesHorizontal("points", formLayout, onKeys, onValues);
+		awardPointEl.setElementCssClass("o_sel_cl_checkbox_award_points");
 		awardPointEl.setVisible(withScore);
 		awardPointEl.addActionListener(FormEvent.ONCHANGE);
 		if(checkbox.getPoints() != null) {
@@ -149,6 +152,7 @@ public class CheckboxEditController extends FormBasicController {
 		}
 		String points = checkbox.getPoints() == null ? null : Float.toString(checkbox.getPoints().floatValue());
 		pointsEl = uifactory.addTextElement("numofpoints", null, 10, points, formLayout);
+		pointsEl.setElementCssClass("o_sel_cl_checkbox_points");
 		pointsEl.setVisible(withScore && awardPointEl.isAtLeastSelected(1));
 		pointsEl.setDisplaySize(5);
 		
diff --git a/src/test/java/org/olat/selenium/CourseElementTest.java b/src/test/java/org/olat/selenium/CourseElementTest.java
index 078f9321b91..d42735e9261 100644
--- a/src/test/java/org/olat/selenium/CourseElementTest.java
+++ b/src/test/java/org/olat/selenium/CourseElementTest.java
@@ -33,6 +33,7 @@ import org.jboss.arquillian.test.api.ArquillianResource;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.olat.course.learningpath.FullyAssessedTrigger;
 import org.olat.repository.RepositoryEntryStatusEnum;
 import org.olat.selenium.page.LoginPage;
 import org.olat.selenium.page.NavigationPage;
@@ -43,6 +44,8 @@ import org.olat.selenium.page.core.ContactPage;
 import org.olat.selenium.page.core.FolderPage;
 import org.olat.selenium.page.core.MenuTreePageFragment;
 import org.olat.selenium.page.course.BigBlueButtonPage;
+import org.olat.selenium.page.course.CheckListConfigPage;
+import org.olat.selenium.page.course.CheckListPage;
 import org.olat.selenium.page.course.ContactConfigPage;
 import org.olat.selenium.page.course.CourseEditorPageFragment;
 import org.olat.selenium.page.course.CoursePageFragment;
@@ -2038,4 +2041,112 @@ public class CourseElementTest extends Deployments {
 			.assertOnMeeting(meetingName)
 			.assertOnJoin();
 	}
+	
+
+	/**
+	 * An author create a course with a course element
+	 * with one check box. It add one participant. The
+	 * participant log in, go to the course to check its
+	 * box and see if it has done the course with 100%.
+	 * 
+	 * @param loginPage The login page
+	 * @throws IOException
+	 * @throws URISyntaxException
+	 */
+	@Test
+	@RunAsClient
+	public void courseWithCheckboxWithScore()
+	throws IOException, URISyntaxException {
+						
+		UserVO author = new UserRestClient(deploymentUrl).createAuthor();
+		UserVO participant = new UserRestClient(deploymentUrl).createRandomUser("ryomou");
+
+		LoginPage loginPage = LoginPage.load(browser, deploymentUrl);
+		loginPage.loginAs(author.getLogin(), author.getPassword());
+		
+		//create a course
+		String courseTitle = "Check Course" + UUID.randomUUID();
+		NavigationPage navBar = NavigationPage.load(browser);
+		CoursePageFragment courseRuntime = navBar
+			.openAuthoringEnvironment()
+			.createCourse(courseTitle, true)
+			.clickToolbarBack();
+		
+		//add participant
+		MembersPage members = courseRuntime
+			.members();
+		members
+			.importMembers()
+			.setMembers(participant)
+			.nextUsers()
+			.nextOverview()
+			.selectRepositoryEntryRole(false, false, true)
+			.nextPermissions()
+			.finish();
+		// back to course
+		members
+			.clickToolbarBack();
+		
+		//create a course element of type Test with the test that we create above
+		String nodeTitle = "CheckNode";
+		CourseEditorPageFragment courseEditor = CoursePageFragment.getCourse(browser)
+			.edit();
+		courseEditor
+			.createNode("checklist")
+			.nodeTitle(nodeTitle);
+		
+		String checkboxTitle = "Do some programming";
+		
+		CheckListConfigPage checkConfig = new CheckListConfigPage(browser);
+		checkConfig
+			.selectListConfiguration()
+			.addCheckbox(checkboxTitle, 4)
+			.assertOnCheckboxInList(checkboxTitle);
+		
+		checkConfig
+			.selectAssessmentConfiguration()
+			.setScoring(0, 4, 3)
+			.saveAssessmentConfiguration();
+		
+		courseEditor
+			.selectTabLearnPath()
+			.setCompletionCriterion(FullyAssessedTrigger.passed)
+			.save();
+		
+		courseEditor
+			.autoPublish()
+			.publish()
+			.settings()
+			.accessConfiguration()
+			.setUserAccess(UserAccess.membersOnly)
+			.save()
+			.clickToolbarBack();
+		
+		
+		//log out
+		new UserToolsPage(browser)
+			.logout();
+		
+		// participant comes in
+		loginPage.loginAs(participant.getLogin(), participant.getPassword());
+
+		NavigationPage ryomouNavBar = NavigationPage.load(browser);
+		ryomouNavBar
+			.openMyCourses()
+			.select(courseTitle);
+		
+		CoursePageFragment course = new CoursePageFragment(browser);
+		course
+			.clickTree()
+			.selectWithTitle(nodeTitle);
+
+		CheckListPage checkPage = new CheckListPage(browser);
+		checkPage
+			.assertOnCheckbox(checkboxTitle)
+			.check(checkboxTitle);
+		// student has done the course
+		course
+			.assertOnLearnPathNodeDone(nodeTitle)
+			.assertOnLearnPathPercent(100);
+	}
 }
diff --git a/src/test/java/org/olat/selenium/page/course/CheckListConfigPage.java b/src/test/java/org/olat/selenium/page/course/CheckListConfigPage.java
new file mode 100644
index 00000000000..123134fd2f6
--- /dev/null
+++ b/src/test/java/org/olat/selenium/page/course/CheckListConfigPage.java
@@ -0,0 +1,109 @@
+/**
+ * <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.course;
+
+import org.olat.selenium.page.graphene.OOGraphene;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * 
+ * Initial date: 3 juil. 2020<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class CheckListConfigPage {
+	
+	private final WebDriver browser;
+	
+	public CheckListConfigPage(WebDriver browser) {
+		this.browser = browser;
+	}
+	
+	public CheckListConfigPage selectListConfiguration() {
+		OOGraphene.scrollTop(browser);
+		By configBy = By.className("o_sel_cl_edit_checklist");
+		OOGraphene.selectTab("o_node_config", configBy, browser);
+		return this;
+	}
+	
+	public CheckListConfigPage addCheckbox(String title, int score) {
+		By addCheckboxBy = By.className("o_sel_cl_new_checkbox");
+		OOGraphene.waitElement(addCheckboxBy, browser);
+		browser.findElement(addCheckboxBy).click();
+		OOGraphene.waitBusy(browser);
+		OOGraphene.waitModalDialog(browser);
+		
+		By titleBy = By.cssSelector("fieldset.o_sel_cl_edit_checkbox_form input.o_sel_cl_checkbox_title[type='text']");
+		OOGraphene.waitElement(titleBy, browser);
+		browser.findElement(titleBy).sendKeys(title);
+		
+		if(score > 0) {
+			By awardPoints = By.cssSelector("fieldset.o_sel_cl_edit_checkbox_form div.o_sel_cl_checkbox_award_points input[type='checkbox']");
+			browser.findElement(awardPoints).click();
+			OOGraphene.waitBusy(browser);
+			
+			By pointsBy = By.cssSelector("fieldset.o_sel_cl_edit_checkbox_form input.o_sel_cl_checkbox_points[type='text']");
+			OOGraphene.waitElement(pointsBy, browser);
+			browser.findElement(pointsBy).sendKeys(Integer.toString(score));
+		}
+		
+		By saveBy = By.cssSelector("fieldset.o_sel_cl_edit_checkbox_form button.btn-primary");
+		browser.findElement(saveBy).click();
+		OOGraphene.waitBusy(browser);
+		OOGraphene.waitModalDialogDisappears(browser);
+		return this;
+	}
+	
+	public CheckListConfigPage assertOnCheckboxInList(String title) {
+		By checkboxBy = By.xpath("//fieldset[contains(@class,'o_sel_cl_edit_checklist')]//div[contains(@class,'o_table_flexi')]/table//td[contains(text(),'" + title + "')]");
+		OOGraphene.waitElement(checkboxBy, browser);
+		return this;
+	}
+	
+	public CheckListConfigPage selectAssessmentConfiguration() {
+		By configBy = By.className("o_sel_cl_edit_assessment");
+		OOGraphene.selectTab("o_node_config", configBy, browser);
+		return this;
+	}
+	
+	public CheckListConfigPage setScoring(int minScore, int maxScore, int cutValue) {
+		By minScoreBy = By.cssSelector("fieldset.o_sel_cl_edit_assessment input.o_sel_cl_min_score[type='text']");
+		OOGraphene.waitElement(minScoreBy, browser);
+		browser.findElement(minScoreBy).sendKeys(Integer.toString(minScore));
+		
+		By maxScoreBy = By.cssSelector("fieldset.o_sel_cl_edit_assessment input.o_sel_cl_max_score[type='text']");
+		browser.findElement(maxScoreBy).sendKeys(Integer.toString(maxScore));
+		
+		By cutValueScoreBy = By.cssSelector("fieldset.o_sel_cl_edit_assessment input.o_sel_cl_cut_value[type='text']");
+		browser.findElement(cutValueScoreBy).sendKeys(Integer.toString(cutValue));
+		
+		return this;
+	}
+	
+	public CheckListConfigPage saveAssessmentConfiguration() {
+		By saveBy = By.cssSelector("fieldset.o_sel_cl_edit_assessment button.btn-primary");
+		browser.findElement(saveBy).click();
+		OOGraphene.waitBusy(browser);
+		OOGraphene.scrollTop(browser);
+		return this;
+	}
+
+}
diff --git a/src/test/java/org/olat/selenium/page/course/CheckListPage.java b/src/test/java/org/olat/selenium/page/course/CheckListPage.java
new file mode 100644
index 00000000000..c5c3710965c
--- /dev/null
+++ b/src/test/java/org/olat/selenium/page/course/CheckListPage.java
@@ -0,0 +1,53 @@
+/**
+ * <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.course;
+
+import org.olat.selenium.page.graphene.OOGraphene;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * 
+ * Initial date: 9 juil. 2020<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class CheckListPage {
+	
+	private final WebDriver browser;
+	
+	public CheckListPage(WebDriver browser) {
+		this.browser = browser;
+	}
+	
+	public CheckListPage assertOnCheckbox(String title) {
+		By titleBy = By.xpath("//h4[@class='o_cl_title'][contains(text(),'" + title + "')]");
+		OOGraphene.waitElement(titleBy, browser);
+		return this;
+	}
+	
+	public CheckListPage check(String title) {
+		By checkBy = By.xpath("//div[contains(@class,'o_cl_line')][div/h4[@class='o_cl_title'][contains(text(),'" + title + "')]]//label/input[@type='checkbox']");
+		browser.findElement(checkBy).click();
+		OOGraphene.waitBusy(browser);
+		return this;
+	}
+
+}
-- 
GitLab