diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/FeedbackEditorController.java b/src/main/java/org/olat/ims/qti21/ui/editor/FeedbackEditorController.java index 9be07617eaffcfbc363d3002f67220bffbf6fa3e..c3523cad7a370d6f46379b921faccd57f1099d59 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/FeedbackEditorController.java +++ b/src/main/java/org/olat/ims/qti21/ui/editor/FeedbackEditorController.java @@ -72,6 +72,7 @@ public class FeedbackEditorController extends FormBasicController { @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { setFormContextHelp("Test editor QTI 2.1 in detail#details_testeditor_feedback"); + formLayout.setElementCssClass("o_sel_assessment_item_feedbacks"); String relativePath = rootDirectory.toPath().relativize(itemFile.toPath().getParent()).toString(); VFSContainer itemContainer = (VFSContainer)rootContainer.resolve(relativePath); @@ -82,12 +83,14 @@ public class FeedbackEditorController extends FormBasicController { hintTitleEl = uifactory.addTextElement("hintTitle", "form.imd.hint.title", -1, hintTitle, formLayout); hintTitleEl.setUserObject(hint); hintTitleEl.setEnabled(!restrictedEdit); + hintTitleEl.setElementCssClass("o_sel_assessment_item_hint_title"); String hintText = hint == null ? "" : hint.getText(); hintTextEl = uifactory.addRichTextElementForQTI21("hintText", "form.imd.hint.text", hintText, 8, -1, itemContainer, formLayout, ureq.getUserSession(), getWindowControl()); hintTextEl.setEnabled(!restrictedEdit); hintTextEl.setHelpTextKey("feedback.hint.help", null); hintTextEl.setHelpUrlForManualPage("Test editor QTI 2.1 in detail#details_testeditor_feedback"); + hintTextEl.setElementCssClass("o_sel_assessment_item_hint"); RichTextConfiguration hintConfig = hintTextEl.getEditorConfiguration(); hintConfig.setFileBrowserUploadRelPath("media");// set upload dir to the media dir } @@ -98,12 +101,14 @@ public class FeedbackEditorController extends FormBasicController { feedbackCorrectSolutionTitleEl = uifactory.addTextElement("correctSolutionTitle", "form.imd.correct.solution.title", -1, correctSolutionTitle, formLayout); feedbackCorrectSolutionTitleEl.setUserObject(correctSolutionFeedback); feedbackCorrectSolutionTitleEl.setEnabled(!restrictedEdit); + feedbackCorrectSolutionTitleEl.setElementCssClass("o_sel_assessment_item_correct_solution_title"); String correctSolutionText = correctSolutionFeedback == null ? "" : correctSolutionFeedback.getText(); feedbackCorrectSolutionTextEl = uifactory.addRichTextElementForQTI21("correctSolutionText", "form.imd.correct.solution.text", correctSolutionText, 8, -1, itemContainer, formLayout, ureq.getUserSession(), getWindowControl()); feedbackCorrectSolutionTextEl.setEnabled(!restrictedEdit); feedbackCorrectSolutionTextEl.setHelpTextKey("feedback.correctsolution.help", null); feedbackCorrectSolutionTextEl.setHelpUrlForManualPage("Test editor QTI 2.1 in detail#details_testeditor_feedback"); + feedbackCorrectSolutionTextEl.setElementCssClass("o_sel_assessment_item_correct_solution"); RichTextConfiguration richTextConfig2 = feedbackCorrectSolutionTextEl.getEditorConfiguration(); richTextConfig2.setFileBrowserUploadRelPath("media");// set upload dir to the media dir } @@ -114,12 +119,14 @@ public class FeedbackEditorController extends FormBasicController { feedbackCorrectTitleEl = uifactory.addTextElement("correctTitle", "form.imd.correct.title", -1, correctTitle, formLayout); feedbackCorrectTitleEl.setUserObject(correctFeedback); feedbackCorrectTitleEl.setEnabled(!restrictedEdit); + feedbackCorrectTitleEl.setElementCssClass("o_sel_assessment_item_correct_feedback_title"); String correctText = correctFeedback == null ? "" : correctFeedback.getText(); feedbackCorrectTextEl = uifactory.addRichTextElementForQTI21("correctText", "form.imd.correct.text", correctText, 8, -1, itemContainer, formLayout, ureq.getUserSession(), getWindowControl()); feedbackCorrectTextEl.setEnabled(!restrictedEdit); feedbackCorrectTextEl.setHelpTextKey("feedback.correct.help", null); feedbackCorrectTextEl.setHelpUrlForManualPage("Test editor QTI 2.1 in detail#details_testeditor_feedback"); + feedbackCorrectTextEl.setElementCssClass("o_sel_assessment_item_correct_feedback"); RichTextConfiguration richTextConfig = feedbackCorrectTextEl.getEditorConfiguration(); richTextConfig.setFileBrowserUploadRelPath("media");// set upload dir to the media dir } @@ -131,12 +138,14 @@ public class FeedbackEditorController extends FormBasicController { feedbackIncorrectTitleEl = uifactory.addTextElement("incorrectTitle", "form.imd.incorrect.title", -1, incorrectTitle, formLayout); feedbackIncorrectTitleEl.setUserObject(incorrectFeedback); feedbackIncorrectTitleEl.setEnabled(!restrictedEdit); + feedbackIncorrectTitleEl.setElementCssClass("o_sel_assessment_item_incorrect_feedback_title"); String incorrectText = incorrectFeedback == null ? "" : incorrectFeedback.getText(); feedbackIncorrectTextEl = uifactory.addRichTextElementForQTI21("incorrectText", "form.imd.incorrect.text", incorrectText, 8, -1, itemContainer, formLayout, ureq.getUserSession(), getWindowControl()); feedbackIncorrectTextEl.setEnabled(!restrictedEdit); feedbackIncorrectTextEl.setHelpTextKey("feedback.incorrect.help", null); feedbackIncorrectTextEl.setHelpUrlForManualPage("Test editor QTI 2.1 in detail#details_testeditor_feedback"); + feedbackIncorrectTextEl.setElementCssClass("o_sel_assessment_item_incorrect_feedback"); RichTextConfiguration richTextConfig2 = feedbackIncorrectTextEl.getEditorConfiguration(); richTextConfig2.setFileBrowserUploadRelPath("media");// set upload dir to the media dir } diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/interactions/ChoiceScoreController.java b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/ChoiceScoreController.java index fb9b1d43e1e49545885f0bfba6db1d87929d83b8..ac1f8b799c9e8324e2eb92b4342ce8aff449edb9 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/interactions/ChoiceScoreController.java +++ b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/ChoiceScoreController.java @@ -89,8 +89,8 @@ public class ChoiceScoreController extends AssessmentItemRefEditorController imp super.initForm(formLayout, listener, ureq); minScoreEl = uifactory.addTextElement("min.score", "min.score", 8, "0.0", formLayout); + minScoreEl.setElementCssClass("o_sel_assessment_item_min_score"); minScoreEl.setEnabled(false); - minScoreEl.setEnabled(!restrictedEdit); ScoreBuilder maxScore = itemBuilder.getMaxScoreBuilder(); String maxValue = maxScore == null ? "" : (maxScore.getScore() == null ? "" : maxScore.getScore().toString()); diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/interactions/_content/choices_score.html b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/_content/choices_score.html index 69ac6be1581b417291ed9ae1a91787239ee3f966..ecf086035635891291be759cba4bc05db0a7ec1c 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/interactions/_content/choices_score.html +++ b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/_content/choices_score.html @@ -1,4 +1,4 @@ -<table class="table"> +<table class="table o_sel_choices_scores"> <thead><tr> <th>$r.translate("form.score.answer.correct")</th> <th>$r.translate("form.score.answer.summary")</th> diff --git a/src/test/java/org/olat/selenium/ImsQTI21Test.java b/src/test/java/org/olat/selenium/ImsQTI21Test.java index d891ae2166435ae80bbe8fa3c95907879fc8ed41..7cc500645dba0f267b10e989d0110ddd87613a06 100644 --- a/src/test/java/org/olat/selenium/ImsQTI21Test.java +++ b/src/test/java/org/olat/selenium/ImsQTI21Test.java @@ -42,7 +42,6 @@ import org.olat.selenium.page.NavigationPage; import org.olat.selenium.page.User; import org.olat.selenium.page.course.CourseEditorPageFragment; import org.olat.selenium.page.course.CoursePageFragment; -import org.olat.selenium.page.qti.QTI21ChoicesScoreEditorPage; import org.olat.selenium.page.qti.QTI21ConfigurationCEPage; import org.olat.selenium.page.qti.QTI21EditorPage; import org.olat.selenium.page.qti.QTI21Page; @@ -939,7 +938,7 @@ public class ImsQTI21Test { */ @Test @RunAsClient - public void choicesEditor(@InitialPage LoginPage authorLoginPage) + public void qti21EditorSingleChoices(@InitialPage LoginPage authorLoginPage) throws IOException, URISyntaxException { UserVO author = new UserRestClient(deploymentUrl).createAuthor(); authorLoginPage.loginAs(author.getLogin(), author.getPassword()); @@ -972,7 +971,32 @@ public class ImsQTI21Test { .addChoice(3) .setAnswer(3, "Nicht richtig") .save(); - QTI21ChoicesScoreEditorPage scScoreEditor = scEditor - .selectScores(); + // change max score + scEditor + .selectScores() + .setMaxScore("3") + .save(); + // set some feedbacks + scEditor + .selectFeedbacks() + .setHint("Hint", "The hint") + .setCorrectSolution("Correct solution", "This is the correct solution") + .setCorrectFeedback("Correct feedback", "This is correct") + .setIncorrectFeedback("Incorrect", "Your answer is not correct") + .save(); + + qtiPage + .clickToolbarBack(); + + qtiPage + .answerSingleChoice("Nicht richtig") + .saveAnswer() + .assertFeedback("Incorrect") + .assertCorrectSolution("Correct solution") + .hint() + .assertFeedback("Hint") + .answerSingleChoice("Correct answer") + .saveAnswer() + .assertFeedback("Correct feedback"); } } diff --git a/src/test/java/org/olat/selenium/page/qti/QTI21ChoicesScoreEditorPage.java b/src/test/java/org/olat/selenium/page/qti/QTI21ChoicesScoreEditorPage.java index a095ae4764c4f78eb1e5903813f993065ac2419e..f7624a06157287d7c40ca9f6027fc3efabd6e965 100644 --- a/src/test/java/org/olat/selenium/page/qti/QTI21ChoicesScoreEditorPage.java +++ b/src/test/java/org/olat/selenium/page/qti/QTI21ChoicesScoreEditorPage.java @@ -19,7 +19,11 @@ */ package org.olat.selenium.page.qti; +import org.olat.ims.qti21.model.xml.interactions.SimpleChoiceAssessmentItemBuilder.ScoreEvaluation; +import org.olat.selenium.page.graphene.OOGraphene; +import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; /** * @@ -29,10 +33,47 @@ import org.openqa.selenium.WebDriver; */ public class QTI21ChoicesScoreEditorPage { + private static final By choiceScoreTable = By.className("o_sel_choices_scores"); + private final WebDriver browser; public QTI21ChoicesScoreEditorPage(WebDriver browser) { this.browser = browser; } + + public QTI21ChoicesScoreEditorPage selectAssessmentMode(ScoreEvaluation mode) { + By modeBy = By.cssSelector("#o_coassessment_mode input[value='" + mode.name() + "']"); + browser.findElement(modeBy).click(); + OOGraphene.waitBusy(browser); + if(mode == ScoreEvaluation.allCorrectAnswers) { + OOGraphene.waitElementDisappears(choiceScoreTable, 5, browser); + } else if (mode == ScoreEvaluation.perAnswer) { + OOGraphene.waitElement(choiceScoreTable, 5, browser); + } + return this; + } + + public QTI21ChoicesScoreEditorPage setScore(String answer, String score) { + By scoreBy = By.xpath("//table[contains(@class,'o_sel_choices_scores')]//tr[td[contains(text(),'" + answer + "')]]/td/div/input[@type='text']"); + WebElement scoreEl = browser.findElement(scoreBy); + scoreEl.clear(); + scoreEl.sendKeys(score); + return this; + } + + public QTI21ChoicesScoreEditorPage setMaxScore(String maxScore) { + By maxScoreBy = By.cssSelector("div.o_sel_assessment_item_max_score input[type='text']"); + WebElement maxScoreEl = browser.findElement(maxScoreBy); + maxScoreEl.clear(); + maxScoreEl.sendKeys(maxScore); + return this; + } + + public QTI21ChoicesScoreEditorPage save() { + By saveBy = By.cssSelector("fieldset.o_sel_assessment_item_options button.btn.btn-primary"); + browser.findElement(saveBy).click(); + OOGraphene.waitBusy(browser); + return this; + } } diff --git a/src/test/java/org/olat/selenium/page/qti/QTI21FeedbacksEditorPage.java b/src/test/java/org/olat/selenium/page/qti/QTI21FeedbacksEditorPage.java new file mode 100644 index 0000000000000000000000000000000000000000..c4554d328d560c949adbcbd69432995eb69203f2 --- /dev/null +++ b/src/test/java/org/olat/selenium/page/qti/QTI21FeedbacksEditorPage.java @@ -0,0 +1,74 @@ +/** + * <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 org.olat.selenium.page.graphene.OOGraphene; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; + +/** + * + * Initial date: 4 mai 2017<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class QTI21FeedbacksEditorPage { + + private final WebDriver browser; + + public QTI21FeedbacksEditorPage(WebDriver browser) { + this.browser = browser; + } + + public QTI21FeedbacksEditorPage setHint(String title, String hint) { + By titleBy = By.cssSelector("div.o_sel_assessment_item_hint_title input[type='text']"); + browser.findElement(titleBy).sendKeys(title); + OOGraphene.tinymce(hint, "div.o_sel_assessment_item_hint", browser); + return this; + } + + public QTI21FeedbacksEditorPage setCorrectSolution(String title, String correctSolution) { + By titleBy = By.cssSelector("div.o_sel_assessment_item_correct_solution_title input[type='text']"); + browser.findElement(titleBy).sendKeys(title); + OOGraphene.tinymce(correctSolution, "div.o_sel_assessment_item_correct_solution", browser); + return this; + } + + public QTI21FeedbacksEditorPage setCorrectFeedback(String title, String feedback) { + By titleBy = By.cssSelector("div.o_sel_assessment_item_correct_feedback_title input[type='text']"); + browser.findElement(titleBy).sendKeys(title); + OOGraphene.tinymce(feedback, "div.o_sel_assessment_item_correct_feedback", browser); + return this; + } + + public QTI21FeedbacksEditorPage setIncorrectFeedback(String title, String feedback) { + By titleBy = By.cssSelector("div.o_sel_assessment_item_incorrect_feedback_title input[type='text']"); + browser.findElement(titleBy).sendKeys(title); + OOGraphene.tinymce(feedback, "div.o_sel_assessment_item_incorrect_feedback", browser); + return this; + } + + public QTI21FeedbacksEditorPage save() { + By saveBy = By.cssSelector("fieldset.o_sel_assessment_item_feedbacks button.btn.btn-primary"); + browser.findElement(saveBy).click(); + OOGraphene.waitBusy(browser); + return this; + } +} 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 0c23be3f3f6ae191c6e9eba53604d4fab5e84d9c..0765f1a5b494a1108f7581f8ba0f518ce05036a0 100644 --- a/src/test/java/org/olat/selenium/page/qti/QTI21Page.java +++ b/src/test/java/org/olat/selenium/page/qti/QTI21Page.java @@ -164,11 +164,22 @@ public class QTI21Page { return this; } - public QTI21Page assertFeedback(String feedback) { - By feedbackBy = By.xpath("//div[contains(@class,'modalFeedback')]/h4[contains(text(),'" + feedback + "')]"); + public QTI21Page assertFeedback(String title) { + By feedbackBy = By.xpath("//div[contains(@class,'modalFeedback')]/h4[contains(text(),'" + title + "')]"); OOGraphene.waitElement(feedbackBy, 5, browser); - List<WebElement> feedbackEls = browser.findElements(feedbackBy); - Assert.assertEquals(1, feedbackEls.size()); + return this; + } + + public QTI21Page assertCorrectSolution(String title) { + By feedbackBy = By.xpath("//div[contains(@class,'modalFeedback')]/h4/a[contains(text(),'" + title + "')]"); + OOGraphene.waitElement(feedbackBy, 5, browser); + return this; + } + + public QTI21Page hint() { + By hintBy = By.cssSelector("a.o_sel_assessment_item_hint"); + browser.findElement(hintBy).click(); + OOGraphene.waitBusy(browser); return this; } diff --git a/src/test/java/org/olat/selenium/page/qti/QTI21SingleChoiceEditorPage.java b/src/test/java/org/olat/selenium/page/qti/QTI21SingleChoiceEditorPage.java index 4dc34383f75d46842fbb723190f43ade3633021e..f518c83876dcbc543854887651d609bf17716da0 100644 --- a/src/test/java/org/olat/selenium/page/qti/QTI21SingleChoiceEditorPage.java +++ b/src/test/java/org/olat/selenium/page/qti/QTI21SingleChoiceEditorPage.java @@ -73,5 +73,10 @@ public class QTI21SingleChoiceEditorPage extends QTI21AssessmentItemEditorPage { selectTab(By.className("o_sel_assessment_item_options")); return new QTI21ChoicesScoreEditorPage(browser); } + + public QTI21FeedbacksEditorPage selectFeedbacks() { + selectTab(By.className("o_sel_assessment_item_feedbacks")); + return new QTI21FeedbacksEditorPage(browser); + } }