diff --git a/src/main/java/org/olat/ims/qti21/ui/components/_content/hotspotInteraction.html b/src/main/java/org/olat/ims/qti21/ui/components/_content/hotspotInteraction.html index 812a87d9af064b5f991200fcf15548cb938bd5a7..bb4aecb47dab5e11f2fd974a1048af2bf741ebf9 100644 --- a/src/main/java/org/olat/ims/qti21/ui/components/_content/hotspotInteraction.html +++ b/src/main/java/org/olat/ims/qti21/ui/components/_content/hotspotInteraction.html @@ -25,8 +25,10 @@ jQuery(function() { jQuery('#${qtiContainerId}_img').maphilight({ fillColor: '888888', - strokeColor: '0000ff', - strokeWidth: 3 + strokeColor: '333333', + strokeOpacity: 0.5, + strokeWidth: 3, + alwaysOn: true }); jQuery('#${qtiContainerId}').hotspotInteraction({ diff --git a/src/main/webapp/static/js/jquery/qti/jquery.hotspot.js b/src/main/webapp/static/js/jquery/qti/jquery.hotspot.js index 83fc52d001a9395c733c6db9eac215eed9ffed43..26823d09e1aa1815ace1be50b581a8482be6dc68 100644 --- a/src/main/webapp/static/js/jquery/qti/jquery.hotspot.js +++ b/src/main/webapp/static/js/jquery/qti/jquery.hotspot.js @@ -29,7 +29,8 @@ for(i=areaIds.length; i-->0; ) { var areaEl = jQuery('#ac_' + settings.responseIdentifier + '_' + areaIds[i]); var data = areaEl.data('maphilight') || {}; - data.alwaysOn = true; + data.selectedOn = true; + colorData(data); areaEl.data('maphilight', data).trigger('alwaysOn.maphilight'); var inputElement = jQuery('<input type="hidden"/>') @@ -51,13 +52,13 @@ function clickHotspotArea(spot, containerId, responseIdentifier, maxChoices) { var areaEl = jQuery(spot); var data = areaEl.data('maphilight') || {}; - if(!data.alwaysOn) { + if((typeof data.selectedOn === "undefined") || !data.selectedOn) { var numOfChoices = maxChoices; if(numOfChoices > 0) { var countChoices = 0; jQuery("area", "map[name='" + containerId + "_map']").each(function(index, el) { var cData = jQuery(el).data('maphilight') || {}; - if(cData.alwaysOn) { + if(cData.selectedOn) { countChoices++; } }); @@ -66,7 +67,13 @@ } } } - data.alwaysOn = !data.alwaysOn; + + if(typeof data.selectedOn === "undefined") { + data.selectedOn = true; + } else { + data.selectedOn = !data.selectedOn; + } + colorData(data); areaEl.data('maphilight', data).trigger('alwaysOn.maphilight'); var divContainer = jQuery('#' + containerId); @@ -74,12 +81,35 @@ jQuery("area", "map[name='" + containerId + "_map']").each(function(index, el) { var cAreaEl = jQuery(el); var cData = cAreaEl.data('maphilight') || {}; - if(cData.alwaysOn) { + if(cData.selectedOn) { var inputElement = jQuery('<input type="hidden"/>') .attr('name', 'qtiworks_response_' + responseIdentifier) .attr('value', cAreaEl.data('qti-id')); divContainer.append(inputElement); } }); + }; + + /* + * Color the data based on the selectedOn flag + */ + function colorData(data) { + if(data.selectedOn) { + data.fillColor = '0000ff'; + data.strokeColor = '0000ff'; + data.strokeOpacity = 1; + data.shadow = true; + data.shadowX = 4; + data.shadowY = 4; + data.shadowRadius = 8; + data.shadowColor = '000000'; + data.shadowOpacity = 0.8; + data.shadowPosition = 'outside'; + } else { + data.fillColor = '888888'; + data.strokeColor = '333333'; + data.strokeOpacity = 0.5; + data.shadow = false; + } } }( jQuery )); diff --git a/src/test/java/org/olat/selenium/ImsQTI21Test.java b/src/test/java/org/olat/selenium/ImsQTI21Test.java index 905e81041865918899e38f73a91fea25bec33cf8..f13f466de13beaf425c2383eabc7818161d0aca6 100644 --- a/src/test/java/org/olat/selenium/ImsQTI21Test.java +++ b/src/test/java/org/olat/selenium/ImsQTI21Test.java @@ -131,7 +131,42 @@ public class ImsQTI21Test { .closeTest() .assertOnAttempts(1); + //TODO continue + } + + /** + * Check if the hotspot interaction send a "correct" feedback. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21GraphicInteractionTest(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "Simple QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/simple_QTI_21_hotspot.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .answerHotspot("circle") + .saveAnswer() + .assertFeedback("Correct!") + .endTest() + .closeTest(); + //TODO check the results } } 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 2d162861fbe794f6481c8460815ddf6eedb5f678..b58b092dcd6f86239cd975da74fb9fcf4816787e 100644 --- a/src/test/java/org/olat/selenium/page/qti/QTI21Page.java +++ b/src/test/java/org/olat/selenium/page/qti/QTI21Page.java @@ -128,6 +128,13 @@ public class QTI21Page { OOGraphene.waitBusy(browser); return this; } + + public QTI21Page answerHotspot(String shape) { + By areaBy = By.cssSelector("div.hotspotInteraction area[shape='" + shape + "']"); + OOGraphene.waitElement(areaBy, 5, browser); + browser.findElement(areaBy).click(); + return this; + } //TODO still QTI 1.2 public QTI21Page answerKPrim(boolean... choices) { @@ -166,6 +173,14 @@ public class QTI21Page { return this; } + public QTI21Page assertFeedback(String feedback) { + By feedbackBy = By.xpath("//div[contains(@class,'modalFeedback')]/h4[contains(text(),'" + feedback + "')]"); + OOGraphene.waitElement(feedbackBy, 5, browser); + List<WebElement> feedbackEls = browser.findElements(feedbackBy); + Assert.assertEquals(1, feedbackEls.size()); + return this; + } + public QTI21Page endTest() { By endBy = By.cssSelector("a.o_sel_end_testpart"); browser.findElement(endBy).click(); diff --git a/src/test/java/org/olat/selenium/page/repository/AuthoringEnvPage.java b/src/test/java/org/olat/selenium/page/repository/AuthoringEnvPage.java index 253c195742c59c78842963d319a587595c8c0b72..340059ed5d75f275842c9a0f27d81b9f2a7b94f9 100644 --- a/src/test/java/org/olat/selenium/page/repository/AuthoringEnvPage.java +++ b/src/test/java/org/olat/selenium/page/repository/AuthoringEnvPage.java @@ -22,6 +22,7 @@ package org.olat.selenium.page.repository; import java.io.File; import org.junit.Assert; +import org.olat.selenium.page.course.CoursePageFragment; import org.olat.selenium.page.course.CourseWizardPage; import org.olat.selenium.page.graphene.OOGraphene; import org.openqa.selenium.By; @@ -196,6 +197,19 @@ public class AuthoringEnvPage { OOGraphene.waitBusy(browser); } + /** + * Click back from the editor + * + * @return + */ + public CoursePageFragment clickToolbarRootCrumb() { + OOGraphene.closeBlueMessageWindow(browser); + By toolbarBackBy = By.xpath("//li[contains(@class,'o_breadcrumb_back')]/following-sibling::li/a"); + browser.findElement(toolbarBackBy).click(); + OOGraphene.waitBusy(browser); + return new CoursePageFragment(browser); + } + public enum ResourceType { course("CourseModule"), cp("FileResource.IMSCP"), diff --git a/src/test/java/org/olat/test/file_resources/simple_QTI_21_hotspot.zip b/src/test/java/org/olat/test/file_resources/simple_QTI_21_hotspot.zip new file mode 100644 index 0000000000000000000000000000000000000000..ba1f401bdf5bc3980e7f203340674fe2bf75f12c Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/simple_QTI_21_hotspot.zip differ