From f950fc2e99766c180cd2a9502960df29f73ce216 Mon Sep 17 00:00:00 2001 From: Marcel Hoekstra Date: Wed, 12 Feb 2025 17:07:35 +0100 Subject: [PATCH] feat: add toggleCorrectResponse method and update GraphicAssociate story for correct response validation --- .../qti-graphic-associate-interaction.ts | 34 +++++++++++++++++++ .../item-show-correct-response.spec.ts | 9 ++++- .../item-show-correct-response.stories.ts | 20 +++++------ 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/lib/qti-components/qti-interaction/qti-graphic-associate-interaction/qti-graphic-associate-interaction.ts b/src/lib/qti-components/qti-interaction/qti-graphic-associate-interaction/qti-graphic-associate-interaction.ts index d6bdc5ed..cf3d9282 100644 --- a/src/lib/qti-components/qti-interaction/qti-graphic-associate-interaction/qti-graphic-associate-interaction.ts +++ b/src/lib/qti-components/qti-interaction/qti-graphic-associate-interaction/qti-graphic-associate-interaction.ts @@ -9,6 +9,7 @@ import styles from './qti-graphic-associate-interaction.styles'; import type { QtiHotspotChoice } from '../qti-hotspot-choice'; import type { CSSResultGroup } from 'lit'; +import type { ResponseVariable } from '../../../exports/variables'; @customElement('qti-graphic-associate-interaction') export class QtiGraphicAssociateInteraction extends Interaction { @@ -18,6 +19,7 @@ export class QtiGraphicAssociateInteraction extends Interaction { private startPoint = null; private endPoint = null; @state() private _lines = []; + @state() private _correctLines = []; @state() private startCoord: { x: number; y: number }; @state() private mouseCoord: { x: number; y: number }; @queryAssignedElements({ selector: 'img' }) private grImage; @@ -29,6 +31,7 @@ export class QtiGraphicAssociateInteraction extends Interaction { reset(): void { this._lines = []; + this._correctLines = []; } validate(): boolean { return this._lines.length > 0; @@ -42,6 +45,21 @@ export class QtiGraphicAssociateInteraction extends Interaction { return this._lines; } + public toggleCorrectResponse(responseVariable: ResponseVariable, show: boolean) { + if (!show) { + this._correctLines = []; + return; + } + if (!responseVariable.correctResponse) { + console.error('No correct response found for this interaction.'); + return; + } + const correctResponses = Array.isArray(responseVariable.correctResponse) + ? responseVariable.correctResponse + : [responseVariable.correctResponse]; + this._correctLines = correctResponses; + } + override render() { return html` @@ -70,6 +88,22 @@ export class QtiGraphicAssociateInteraction extends Interaction { /> ` )} + ${repeat( + this._correctLines, + line => line, + (line, _index) => svg` + (`[identifier=${line.split(' ')[0]}]`).style.left)} + y1=${parseInt(this.querySelector(`[identifier=${line.split(' ')[0]}]`).style.top)} + x2=${parseInt(this.querySelector(`[identifier=${line.split(' ')[1]}]`).style.left)} + y2=${parseInt(this.querySelector(`[identifier=${line.split(' ')[1]}]`).style.top)} + stroke="green" + stroke-width="3" + stroke-dasharray="5,5" + /> + ` + )} ${this.startPoint && svg` { await setupStory(GraphicOrderStory, canvasElement); await graphicOrderStory.play({ canvasElement }); }); + + test('show correct response - GraphicAssociate', async () => { + await setupStory(GraphicAssociateStory, canvasElement); + await graphicAssociateStory.play({ canvasElement }); + }); }); diff --git a/src/lib/qti-item/core/components/item-show-correct-response.stories.ts b/src/lib/qti-item/core/components/item-show-correct-response.stories.ts index 0286b727..96ec0a94 100644 --- a/src/lib/qti-item/core/components/item-show-correct-response.stories.ts +++ b/src/lib/qti-item/core/components/item-show-correct-response.stories.ts @@ -351,16 +351,15 @@ export const GraphicAssociate: Story = { padding: 1rem; display: block; aspect-ratio: 4 / 3; - width: 800px; - border: 2px solid blue; - transform: scale(0.75); + transform: scale(0.7); transform-origin: top left; } + `, play: async ({ canvasElement, step }) => { @@ -380,14 +379,11 @@ export const GraphicAssociate: Story = { const itemContainer = canvasElement.querySelector('item-container'); const interaction = itemContainer.shadowRoot.querySelector('qti-graphic-associate-interaction'); const showCorrectButton = canvas.getAllByShadowText(/Show correct/i)[0]; - // await step('Click on the Show Correct button', async () => { - // await showCorrectButton.click(); - // const hotspotChoice = interaction.querySelectorAll('qti-hotspot-choice'); - // // const get after content - // expect(window.getComputedStyle(hotspotChoice[0], ':after').content).toBe('"C=1"'); - // expect(window.getComputedStyle(hotspotChoice[1], ':after').content).toBe('"C=4"'); - // expect(window.getComputedStyle(hotspotChoice[2], ':after').content).toBe('"C=2"'); - // expect(window.getComputedStyle(hotspotChoice[3], ':after').content).toBe('"C=3"'); - // }); + await step('Click on the Show Correct button', async () => { + await showCorrectButton.click(); + const lines = + interaction.shadowRoot.querySelector('line-container').querySelectorAll(`[part='correct-line']`).length === 2; + expect(lines).toBe(true); + }); } };