Skip to content
Snippets Groups Projects
Commit 61b1f850 authored by srosse's avatar srosse
Browse files

OO-2969 : selenium which use complex conditional feedbacks for QTI 2.1 question

parent 67986048
No related branches found
No related tags found
No related merge requests found
......@@ -388,7 +388,9 @@ public class FeedbacksEditorController extends FormBasicController implements Sy
titleEl.setEnabled(!restrictedEdit);
titleEl.setElementCssClass("o_sel_assessment_item_" + feedbackType.name() + "_feedback_title");
conditionListContainer = FormLayoutContainer.createBareBoneFormLayout("cond_list_".concat(id), getTranslator());
String conditionListPage = velocity_root + "/feedback_condition_list.html";
conditionListContainer = FormLayoutContainer.createCustomFormLayout("cond_list_".concat(id),
getTranslator(), conditionListPage);
formLayout.add(conditionListContainer);
conditionListContainer.setRootForm(mainForm);
conditionListContainer.contextPut("conditions", conditions);
......@@ -547,6 +549,10 @@ public class FeedbacksEditorController extends FormBasicController implements Sy
this.condition = condition;
}
public FormLayoutContainer getRuleContainer() {
return ruleContainer;
}
public void initForm(FormItemContainer feedbackFormLayout) {
String id = Integer.toString(counter.incrementAndGet());
......
<div class='form-inline o_condition'>
$r.render("var_$id")
$r.render("ope_$id")
#if($r.visible("txt_val_$id"))
$r.render("txt_val_$id")
#end
#if($r.visible("ans_$id"))
$r.render("ans_$id")
#end
#if($r.available("add_$id"))
$r.render("add_$id")
#end
#if($r.available("del_$id"))
$r.render("del_$id")
#end
$r.render("var_$id")
$r.render("ope_$id")
#if($r.visible("txt_val_$id"))
$r.render("txt_val_$id")
#end
#if($r.visible("ans_$id"))
$r.render("ans_$id")
#end
#if($r.available("add_$id"))
$r.render("add_$id")
#end
#if($r.available("del_$id"))
$r.render("del_$id")
#end
#if($f.hasError("var_$id"))
<br/>$r.render("var_${id}_ERROR")
#end
#if($f.hasError("txt_val_$id"))
<br/>$r.render("txt_val_${id}_ERROR")
#end
</div>
#foreach($condition in $conditions)
<div class='form-inline o_condition o_condition_${foreach.count}'>$r.render($condition.ruleContainer)</div>
#end
......@@ -1326,6 +1326,108 @@ public class ImsQTI21Test {
.assertOnAssessmentResults()
.assertOnAssessmentTestScore(6);// 3 points from the first question, 3 from the second
}
/**
* Test the conditional feedback with 3 conditions based
* on attempts (and an incorrect feedback used as marker),
* on score and on response. It's done with a multiple
* choice with score per answer and a negative min. score.
*
* @param authorLoginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void qti21EditorMultipleChoices_complexConditionalFeedback(@InitialPage LoginPage authorLoginPage)
throws IOException, URISyntaxException {
UserVO author = new UserRestClient(deploymentUrl).createAuthor();
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();
qtiEditor
.selectNode("Single choice")
.deleteNode();
//add a single choice: all answers score
QTI21MultipleChoiceEditorPage mcEditor = qtiEditor
.addMultipleChoice();
mcEditor
.setAnswer(0, "Ok")
.setCorrect(0)
.addChoice(1)
.setCorrect(1)
.setAnswer(1, "Correct")
.addChoice(2)
.setAnswer(2, "Faux")
.addChoice(3)
.setAnswer(3, "Falsch")
.save();
//add negative scores to play with
mcEditor
.selectScores()
.selectAssessmentMode(ScoreEvaluation.perAnswer)
.setScore("Ok", "3")
.setScore("Correct", "1")
.setScore("Faux", "-1")
.setScore("Falsch", "-1")
.setMaxScore("4")
.save();
// set a conditional feedback
mcEditor
.selectFeedbacks()
.setIncorrectFeedback("Incorrect", "Not the right response")
// attempts = 1 && score < 0
.addConditionalFeedback(1, "NegativeFirstAttempts", "Negative score")
.setCondition(1, 1, Variable.attempts, Operator.equals, "1")
.addCondition(1, 1)
.setCondition(1, 2, Variable.score, Operator.smaller, "0")
// response = 'Faux'
.addConditionalFeedback(2, "FauxAnswer", "You choose the 'Faux' answer")
.setCondition(2, 1, Variable.response, Operator.equals, "Faux")
// 0 < score < 3
.addConditionalFeedback(3, "Positive", "Score between 0 and 3")
.setCondition(3, 1, Variable.score, Operator.biggerEquals, "0")
.addCondition(3, 1)
.setCondition(3, 2, Variable.score, Operator.smaller, "3")
.save();
qtiPage
.clickToolbarBack()
.assertOnAssessmentItem()
//1 attempt, score -2.0
.answerMultipleChoice("Falsch", "Faux")
.saveAnswer()
.assertFeedback("Incorrect")
.assertFeedback("FauxAnswer")
.assertFeedback("NegativeFirstAttempts")
.assertNoFeedback("Positive")
//2 attempt, score 0.0
.deselectAnswerMultipleChoice("Faux", "Falsch")
.answerMultipleChoice("Faux", "Correct")
.saveAnswer()
.assertFeedback("Incorrect")
.assertFeedback("FauxAnswer")
.assertFeedback("Positive")
.assertNoFeedback("NegativeFirstAttempts")
//3 attempt
.deselectAnswerMultipleChoice("Faux")
.answerMultipleChoice("Ok")
.saveAnswer()
.assertNoFeedback()
.endTest();
}
/**
* An author make a test with 2 kprims.<br>
......
......@@ -126,29 +126,44 @@ public class QTI21FeedbacksEditorPage {
public QTI21FeedbacksEditorPage setCondition(int feedbackPosition, int conditionPosition,
ModalFeedbackCondition.Variable variable, ModalFeedbackCondition.Operator operator, String value) {
String conditionPrefix = "//fieldset[contains(@class,'o_sel_assessment_item_additional_" + feedbackPosition + "')]"
+ "//div[contains(@class,'o_condition_" + conditionPosition + "')]";
String feedbackPrefix = "//fieldset[contains(@class,'o_sel_assessment_item_additional_" + feedbackPosition + "')]";
String conditionPrefix = "//div[contains(@class,'o_condition')][" + conditionPosition + "]";
By conditionBy = By.xpath(feedbackPrefix + conditionPrefix);
By conditionBy = By.xpath(conditionPrefix);
OOGraphene.waitElement(conditionBy, browser);
By variableBy = By.xpath(feedbackPrefix + conditionPrefix + "//select[contains(@id,'o_fiovar_')]");
By variableBy = By.xpath(conditionPrefix + "//select[contains(@id,'o_fiovar_')]");
WebElement variableEl = browser.findElement(variableBy);
new Select(variableEl).selectByValue(variable.name());
OOGraphene.waitBusy(browser);
By operatorBy = By.xpath(feedbackPrefix + conditionPrefix + "//select[contains(@id,'o_fioope_')]");
By operatorBy = By.xpath(conditionPrefix + "//select[contains(@id,'o_fioope_')]");
WebElement operatorEl = browser.findElement(operatorBy);
new Select(operatorEl).selectByValue(operator.name());
if(variable == Variable.attempts || variable == Variable.score) {
By valueBy = By.xpath(feedbackPrefix + conditionPrefix + "//input[@type='text']");
By valueBy = By.xpath(conditionPrefix + "//input[@type='text']");
WebElement valueEl = browser.findElement(valueBy);
valueEl.clear();
valueEl.sendKeys(value);
} else if(variable == Variable.response) {
By answerBy = By.xpath(conditionPrefix + "//select[contains(@id,'o_fioans_')]");
WebElement answerEl = browser.findElement(answerBy);
new Select(answerEl).selectByVisibleText(value);
}
return this;
}
public QTI21FeedbacksEditorPage addCondition(int feedbackPosition, int conditionPosition) {
String conditionXpath = "//fieldset[contains(@class,'o_sel_assessment_item_additional_" + feedbackPosition + "')]"
+ "//div[contains(@class,'o_condition_" + conditionPosition + "')]"
+ "//a[contains(@class,'btn-default')][i[contains(@class,'o_icon_add')]]";
By addConditionBy = By.xpath(conditionXpath);
OOGraphene.waitElement(addConditionBy, browser);
browser.findElement(addConditionBy).click();
OOGraphene.waitBusy(browser);
return this;
}
......
/**
* <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.io.File;
......
......@@ -285,6 +285,12 @@ public class QTI21Page {
return this;
}
public QTI21Page assertNoFeedback(String title) {
By feedbackBy = By.xpath("//div[contains(@class,'modalFeedback')]/h4[contains(text(),'" + title + "')]");
OOGraphene.waitElementDisappears(feedbackBy, 5, browser);
return this;
}
/**
* Check that there are no feedbacks visible.
*
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment