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

no-jira: add 2 seleniums test for the numerical input editor

parent 15510d04
No related branches found
No related tags found
No related merge requests found
...@@ -78,9 +78,12 @@ public class FIBNumericalEntrySettingsController extends FormBasicController { ...@@ -78,9 +78,12 @@ public class FIBNumericalEntrySettingsController extends FormBasicController {
@Override @Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
formLayout.setElementCssClass("o_sel_gap_numeric_form");
Double solution = interaction.getSolution(); Double solution = interaction.getSolution();
String solString = solution == null ? "" : solution.toString(); String solString = solution == null ? "" : solution.toString();
solutionEl = uifactory.addTextElement("fib.solution", "fib.solution", 256, solString, formLayout); solutionEl = uifactory.addTextElement("fib.solution", "fib.solution", 256, solString, formLayout);
solutionEl.setElementCssClass("o_sel_gap_numeric_solution");
solutionEl.setEnabled(!restrictedEdit); solutionEl.setEnabled(!restrictedEdit);
if(!restrictedEdit && !StringHelper.containsNonWhitespace(solString)) { if(!restrictedEdit && !StringHelper.containsNonWhitespace(solString)) {
solutionEl.setFocus(true); solutionEl.setFocus(true);
...@@ -88,6 +91,7 @@ public class FIBNumericalEntrySettingsController extends FormBasicController { ...@@ -88,6 +91,7 @@ public class FIBNumericalEntrySettingsController extends FormBasicController {
String placeholder = interaction.getPlaceholder(); String placeholder = interaction.getPlaceholder();
placeholderEl = uifactory.addTextElement("fib.placeholder", "fib.placeholder", 256, placeholder, formLayout); placeholderEl = uifactory.addTextElement("fib.placeholder", "fib.placeholder", 256, placeholder, formLayout);
placeholderEl.setElementCssClass("o_sel_gap_numeric_placeholder");
placeholderEl.setEnabled(!restrictedEdit); placeholderEl.setEnabled(!restrictedEdit);
Integer expectedLength = interaction.getExpectedLength(); Integer expectedLength = interaction.getExpectedLength();
...@@ -131,6 +135,7 @@ public class FIBNumericalEntrySettingsController extends FormBasicController { ...@@ -131,6 +135,7 @@ public class FIBNumericalEntrySettingsController extends FormBasicController {
} }
lowerToleranceEl = uifactory.addTextElement("fib.tolerance.low", "fib.tolerance.low", 8, lowerToleranceString, formLayout); lowerToleranceEl = uifactory.addTextElement("fib.tolerance.low", "fib.tolerance.low", 8, lowerToleranceString, formLayout);
lowerToleranceEl.setExampleKey("fib.tolerance.mode.absolute.example", null); lowerToleranceEl.setExampleKey("fib.tolerance.mode.absolute.example", null);
lowerToleranceEl.setElementCssClass("o_sel_gap_numeric_lower_bound");
lowerToleranceEl.setEnabled(!restrictedEdit); lowerToleranceEl.setEnabled(!restrictedEdit);
Double upperTolerance = interaction.getUpperTolerance(); Double upperTolerance = interaction.getUpperTolerance();
...@@ -150,6 +155,7 @@ public class FIBNumericalEntrySettingsController extends FormBasicController { ...@@ -150,6 +155,7 @@ public class FIBNumericalEntrySettingsController extends FormBasicController {
} }
upperToleranceEl = uifactory.addTextElement("fib.tolerance.up", "fib.tolerance.up", 8, upperToleranceString, formLayout); upperToleranceEl = uifactory.addTextElement("fib.tolerance.up", "fib.tolerance.up", 8, upperToleranceString, formLayout);
upperToleranceEl.setExampleKey("fib.tolerance.mode.absolute.example", null); upperToleranceEl.setExampleKey("fib.tolerance.mode.absolute.example", null);
upperToleranceEl.setElementCssClass("o_sel_gap_numeric_upper_bound");
upperToleranceEl.setEnabled(!restrictedEdit); upperToleranceEl.setEnabled(!restrictedEdit);
updateToleranceUpAndLow(); updateToleranceUpAndLow();
......
...@@ -65,6 +65,7 @@ import org.openqa.selenium.By; ...@@ -65,6 +65,7 @@ import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import uk.ac.ed.ph.jqtiplus.node.expression.operator.ToleranceMode;
import uk.ac.ed.ph.jqtiplus.value.Cardinality; import uk.ac.ed.ph.jqtiplus.value.Cardinality;
/** /**
...@@ -1969,7 +1970,7 @@ public class ImsQTI21Test { ...@@ -1969,7 +1970,7 @@ public class ImsQTI21Test {
UserVO rei = new UserRestClient(deploymentUrl).createRandomUser("Rei"); UserVO rei = new UserRestClient(deploymentUrl).createRandomUser("Rei");
authorLoginPage.loginAs(author.getLogin(), author.getPassword()); authorLoginPage.loginAs(author.getLogin(), author.getPassword());
String qtiTestTitle = "Hotspot QTI 2.1 " + UUID.randomUUID(); String qtiTestTitle = "FIB QTI 2.1 " + UUID.randomUUID();
navBar navBar
.openAuthoringEnvironment() .openAuthoringEnvironment()
.createQTI21Test(qtiTestTitle) .createQTI21Test(qtiTestTitle)
...@@ -2117,6 +2118,348 @@ public class ImsQTI21Test { ...@@ -2117,6 +2118,348 @@ public class ImsQTI21Test {
.assertOnAssessmentTestScore(6);// 2 points from the first question, 4 from the second .assertOnAssessmentTestScore(6);// 2 points from the first question, 4 from the second
} }
/**
* An author make a test with 2 questions using numerical input,
* the first with the score set if all answers are correct, the second
* with scoring per answers. The numerical input have all the tolerance
* mode set to EXACT.<br>
* A first user make the test, but doesn't answer all questions
* correctly, log out and a second user make the perfect test.
*
* @param authorLoginPage
* @param participantBrowser
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void qti21EditorNumericalInput_exact(@InitialPage LoginPage authorLoginPage,
@Drone @User WebDriver participantBrowser)
throws IOException, URISyntaxException {
UserVO author = new UserRestClient(deploymentUrl).createAuthor();
UserVO ryomou = new UserRestClient(deploymentUrl).createRandomUser("Ryomou");
UserVO rei = new UserRestClient(deploymentUrl).createRandomUser("Rei");
authorLoginPage.loginAs(author.getLogin(), author.getPassword());
String qtiTestTitle = "Numerical QTI 2.1 " + UUID.randomUUID();
navBar
.openAuthoringEnvironment()
.createQTI21Test(qtiTestTitle)
.clickToolbarBack();
QTI21Page qtiPage = QTI21Page
.getQTI12Page(browser);
QTI21EditorPage qtiEditor = qtiPage
.edit();
//start a blank test
qtiEditor
.selectNode("Single choice")
.deleteNode();
//add a numerical input: all answers score, tolerance exact
QTI21GapEntriesEditorPage fibEditor = qtiEditor
.addNumerical()
.appendContent("One plus two: ")
.addNumericalInput("3", "three", ToleranceMode.EXACT, null, null)
.saveNumericInput()
.editNumericalInput("9", "nine", ToleranceMode.EXACT, null, null, 2)
.saveNumericInput()
.save();
//set max score
fibEditor
.selectScores()
.selectAssessmentMode(ScoreEvaluation.allCorrectAnswers)
.setMaxScore("2")
.save();
// set feedbacks
fibEditor
.selectFeedbacks()
.setHint("Hint", "The second is the first power two")
.setCorrectSolution("Correct solution", "I know you know")
.setCorrectFeedback("Correct feedback", "Your answer is correct")
.setIncorrectFeedback("Incorrect", "Your answer is not correct")
.save();
//add a gap entry: score per answer, tolerance exact
fibEditor = qtiEditor
.addNumerical()
.appendContent("More difficult: 34 + 23 ")
.addNumericalInput("57", "57", ToleranceMode.EXACT, null, null)
.saveNumericInput()
.editNumericalInput("8", "64squareroot",ToleranceMode.EXACT, null, null, 2)
.saveNumericInput()
.save();
//set max score
fibEditor
.selectScores()
.selectAssessmentMode(ScoreEvaluation.perAnswer)
.setMaxScore("4")
.setScore("57", "2")
.setScore("8", "3")
.save();
// set feedbacks
fibEditor
.selectFeedbacks()
.setHint("Hint", "The second is the square root of 64")
.setCorrectSolution("Correct solution", "This is an information about the correct solution")
.setCorrectFeedback("Correct feedback", "Your answer is correct")
.setIncorrectFeedback("Incorrect", "Your answer is not correct")
.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();
// first user make the test
QTI21Page ryomouQtiPage = QTI21Page
.getQTI12Page(participantBrowser);
ryomouQtiPage
.assertOnAssessmentItem()
.answerGapTextWithPlaceholder("2", "three")
.answerGapTextWithPlaceholder("25", "nine")
.saveAnswer()
.assertFeedback("Incorrect")
.assertCorrectSolution("Correct solution")
.hint()
.assertFeedback("Hint")
.answerGapTextWithPlaceholder("3", "three")
.answerGapTextWithPlaceholder("9", "nine")
.saveAnswer()
.assertFeedback("Correct feedback")
.nextAnswer()
.answerGapTextWithPlaceholder("57", "57")
.answerGapTextWithPlaceholder("9", "64squareroot")
.saveAnswer()
.assertCorrectSolution("Correct solution")
.assertFeedback("Incorrect")
.endTest()
.assertOnAssessmentResults()
.assertOnAssessmentTestScore(4);// 2 points from the first question, 4 from the second
//a second user search the content package
LoginPage reiLoginPage = LoginPage.getLoginPage(participantBrowser, deploymentUrl);
reiLoginPage
.loginAs(rei.getLogin(), rei.getPassword())
.resume();
NavigationPage reiNavBar = new NavigationPage(participantBrowser);
reiNavBar
.openMyCourses()
.openSearch()
.extendedSearch(qtiTestTitle)
.select(qtiTestTitle)
.start();
// make the test with all the correct answers
QTI21Page
.getQTI12Page(participantBrowser)
.assertOnAssessmentItem()
.answerGapTextWithPlaceholder("3", "three")
.answerGapTextWithPlaceholder("9", "nine")
.saveAnswer()
.assertFeedback("Correct feedback")
.nextAnswer()
.answerGapTextWithPlaceholder("57", "57")
.answerGapTextWithPlaceholder("8", "64squareroot")
.saveAnswer()
.endTest()
.assertOnAssessmentResults()
.assertOnAssessmentTestScore(6);// 2 points from the first question, 4 from the second
}
/**
* An author make a test with 2 questions using numerical input to
* test the absolute tolerance mode.<br>
* A first user make the test, but doesn't answer all questions
* correctly, log out and a second user make the perfect test but
* on the limit.
*
* @param authorLoginPage
* @param participantBrowser
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void qti21EditorNumericalInput_absolut(@InitialPage LoginPage authorLoginPage,
@Drone @User WebDriver participantBrowser)
throws IOException, URISyntaxException {
UserVO author = new UserRestClient(deploymentUrl).createAuthor();
UserVO ryomou = new UserRestClient(deploymentUrl).createRandomUser("Ryomou");
UserVO rei = new UserRestClient(deploymentUrl).createRandomUser("Rei");
authorLoginPage.loginAs(author.getLogin(), author.getPassword());
String qtiTestTitle = "Numerical QTI 2.1 " + UUID.randomUUID();
navBar
.openAuthoringEnvironment()
.createQTI21Test(qtiTestTitle)
.clickToolbarBack();
QTI21Page qtiPage = QTI21Page
.getQTI12Page(browser);
QTI21EditorPage qtiEditor = qtiPage
.edit();
//start a blank test
qtiEditor
.selectNode("Single choice")
.deleteNode();
//add a numerical input: 3.1 - 3.2
QTI21GapEntriesEditorPage fibEditor = qtiEditor
.addNumerical()
.appendContent("Usefull for circles ")
.editNumericalInput("3.1416", "pi", ToleranceMode.ABSOLUTE, "3.2", "3.1", 1)
.saveNumericInput()
.save();
// use standard score setting
// set feedbacks
fibEditor
.selectFeedbacks()
.setCorrectFeedback("Correct feedback", "Your answer is correct")
.setIncorrectFeedback("Incorrect", "Out of bounds")
.save();
//add a numerical input which represent a rounding issue
fibEditor = qtiEditor
.addNumerical()
.appendContent("Check rounding issue ")
.editNumericalInput("14.923", "rounding", ToleranceMode.ABSOLUTE, "14.925", "14.915", 1)
.saveNumericInput()
.save();
// set feedbacks
fibEditor
.selectFeedbacks()
.setCorrectFeedback("Correct feedback", "Your answer is correct")
.setIncorrectFeedback("Incorrect", "Your answer is not correct")
.save();
//add a numerical input with negative values
fibEditor = qtiEditor
.addNumerical()
.appendContent("Check rounding issue ")
.editNumericalInput("-14.923", "negative", ToleranceMode.ABSOLUTE, "-14.921", "-14.931", 1)
.saveNumericInput()
.save();
// set feedbacks
fibEditor
.selectFeedbacks()
.setCorrectFeedback("Correct feedback", "Your answer is correct")
.setIncorrectFeedback("Incorrect", "Your answer is not correct")
.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();
// first user make the test
QTI21Page ryomouQtiPage = QTI21Page
.getQTI12Page(participantBrowser);
ryomouQtiPage
.assertOnAssessmentItem()
.answerGapTextWithPlaceholder("3", "pi")
.saveAnswer()
.assertFeedback("Incorrect")
.answerGapTextWithPlaceholder("3.15", "pi")
.saveAnswer()
.assertFeedback("Correct feedback")
.nextAnswer()
.answerGapTextWithPlaceholder("14.914", "rounding")
.saveAnswer()
.assertFeedback("Incorrect")
.answerGapTextWithPlaceholder("14.915", "rounding")
.saveAnswer()
.assertFeedback("Correct feedback")
.nextAnswer()
.answerGapTextWithPlaceholder("-14.932", "negative")
.saveAnswer()
.assertFeedback("Incorrect")
.answerGapTextWithPlaceholder("-14.920", "negative")
.saveAnswer()
.endTest()
.assertOnAssessmentResults()
.assertOnAssessmentTestScore(2);// 1 point + 1 point + 0 point
//a second user search the content package
LoginPage reiLoginPage = LoginPage.getLoginPage(participantBrowser, deploymentUrl);
reiLoginPage
.loginAs(rei.getLogin(), rei.getPassword())
.resume();
NavigationPage reiNavBar = new NavigationPage(participantBrowser);
reiNavBar
.openMyCourses()
.openSearch()
.extendedSearch(qtiTestTitle)
.select(qtiTestTitle)
.start();
// make the test with all the correct answers
QTI21Page
.getQTI12Page(participantBrowser)
.assertOnAssessmentItem()
.answerGapTextWithPlaceholder("3.2", "pi")
.saveAnswer()
.assertFeedback("Correct feedback")
.nextAnswer()
.answerGapTextWithPlaceholder("14.925", "rounding")
.saveAnswer()
.assertFeedback("Correct feedback")
.nextAnswer()
.answerGapTextWithPlaceholder("-14.921", "negative")
.saveAnswer()
.assertFeedback("Correct feedback")
.endTest()
.assertOnAssessmentResults()
.assertOnAssessmentTestScore(3);
}
/** /**
* An author make a test with 2 matches. A match with "multiple selection" * An author make a test with 2 matches. A match with "multiple selection"
* and score "all answers", a second with "single selection" and score * and score "all answers", a second with "single selection" and score
......
...@@ -147,6 +147,11 @@ public class QTI21EditorPage { ...@@ -147,6 +147,11 @@ public class QTI21EditorPage {
return new QTI21GapEntriesEditorPage(browser); return new QTI21GapEntriesEditorPage(browser);
} }
public QTI21GapEntriesEditorPage addNumerical() {
addQuestion(QTI21QuestionType.numerical);
return new QTI21GapEntriesEditorPage(browser);
}
private QTI21EditorPage addQuestion(QTI21QuestionType type) { private QTI21EditorPage addQuestion(QTI21QuestionType type) {
openElementsMenu(); openElementsMenu();
......
...@@ -23,6 +23,9 @@ import org.olat.selenium.page.graphene.OOGraphene; ...@@ -23,6 +23,9 @@ import org.olat.selenium.page.graphene.OOGraphene;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;
import uk.ac.ed.ph.jqtiplus.node.expression.operator.ToleranceMode;
/** /**
* *
...@@ -106,6 +109,86 @@ public class QTI21GapEntriesEditorPage extends QTI21AssessmentItemEditorPage { ...@@ -106,6 +109,86 @@ public class QTI21GapEntriesEditorPage extends QTI21AssessmentItemEditorPage {
return this; return this;
} }
/**
* Add a new numerical input. Use the placeholder to locate
* the gap during the test.
*
* @param solution The solution
* @param placeholder The placeholder
* @return Itself
*/
public QTI21GapEntriesEditorPage addNumericalInput(String solution, String placeholder,
ToleranceMode toleranceMode, String uperrBound, String lowerBound) {
By addGapBy = By.xpath("//div[contains(@class,'o_sel_assessment_item_fib_text')]//button[i[contains(@class,'mce-i-gapnumerical')]]");
browser.findElement(addGapBy).click();
OOGraphene.waitModalDialog(browser);
return fillNumericalInputSettings(solution, placeholder, toleranceMode, uperrBound, lowerBound);
}
/**
* Edit an existing numerical input of type text. Use the placeholder to locate
* the gap during the test.
*
* @param solution The solution
* @param placeholder The placeholder
* @param index The index of the entry in the paragraph
* @return Itself
*/
public QTI21GapEntriesEditorPage editNumericalInput(String solution, String placeholder,
ToleranceMode toleranceMode, String uperrBound, String lowerBound, int index) {
By frameBy = By.cssSelector("div.o_sel_assessment_item_fib_text div.mce-edit-area iframe");
WebElement frameEl = browser.findElement(frameBy);
browser.switchTo().frame(frameEl);
By gapEntryBy = By.xpath("//p/span[@class='textentryinteraction'][" + index + "]/a");
browser.findElement(gapEntryBy).click();
browser.switchTo().defaultContent();
OOGraphene.waitModalDialog(browser);
return fillNumericalInputSettings(solution, placeholder, toleranceMode, uperrBound, lowerBound);
}
private QTI21GapEntriesEditorPage fillNumericalInputSettings(String solution, String placeholder,
ToleranceMode toleranceMode, String upperBound, String lowerBound) {
By solutionBy = By.cssSelector("fieldset.o_sel_gap_numeric_form div.o_sel_gap_numeric_solution input[type=text]");
WebElement solutionEl = browser.findElement(solutionBy);
solutionEl.clear();
solutionEl.sendKeys(solution);
By placeholderBy = By.cssSelector("fieldset.o_sel_gap_numeric_form div.o_sel_gap_numeric_placeholder input[type=text]");
browser.findElement(placeholderBy).sendKeys(placeholder);
By toleranceModeBy = By.xpath("//select[contains(@id,'fib_tolerance_mode')]");
WebElement toleranceModeEl = browser.findElement(toleranceModeBy);
new Select(toleranceModeEl).selectByValue(toleranceMode.name());
OOGraphene.waitBusy(browser);
By upperBoundBy = By.cssSelector("fieldset.o_sel_gap_numeric_form div.o_sel_gap_numeric_upper_bound input[type=text]");
if(toleranceMode == ToleranceMode.EXACT) {
OOGraphene.waitElementDisappears(upperBoundBy, 5, browser);
} else {
OOGraphene.waitElement(upperBoundBy, browser);
browser.findElement(upperBoundBy).sendKeys(upperBound);
By lowerBoundBy = By.cssSelector("fieldset.o_sel_gap_numeric_form div.o_sel_gap_numeric_lower_bound input[type=text]");
browser.findElement(lowerBoundBy).sendKeys(lowerBound);
}
return this;
}
/**
* Save and close the modal dialog to edit the numerical input.
*
* @return Itself
*/
public QTI21GapEntriesEditorPage saveNumericInput() {
By saveBy = By.cssSelector("fieldset.o_sel_gap_numeric_form button.btn-primary");
browser.findElement(saveBy).click();
OOGraphene.waitBusy(browser);
return this;
}
/** /**
* Save the whole interaction. * Save the whole interaction.
* *
......
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