diff --git a/cypress/e2e/DoenetML/tagSpecific/animatefromsequence.cy.js b/cypress/e2e/DoenetML/tagSpecific/animatefromsequence.cy.js index dfecf317d5..3f69e5f6a5 100644 --- a/cypress/e2e/DoenetML/tagSpecific/animatefromsequence.cy.js +++ b/cypress/e2e/DoenetML/tagSpecific/animatefromsequence.cy.js @@ -1534,8 +1534,8 @@ describe('AnimateFromSequence Tag Tests', function () { cy.window().then(async (win) => { let stateVariables = await win.returnAllStateVariables1(); expect(stateVariables['/x'].stateValues.value).eq(1); - expect(stateVariables['/nl'].stateValues.numbers).eqls([1,2,3]); - expect(stateVariables['/nl2'].stateValues.numbers).eqls([1,2,3]); + expect(stateVariables['/nl'].stateValues.numbers).eqls([1, 2, 3]); + expect(stateVariables['/nl2'].stateValues.numbers).eqls([1, 2, 3]); expect(stateVariables['/x'].stateValues.selectedIndex).eq(1); expect(stateVariables['/x'].stateValues.animationOn).eq(false); }) @@ -1565,14 +1565,14 @@ describe('AnimateFromSequence Tag Tests', function () { lastValue1 = stateVariables['/x'].stateValues.value; expect(lastValue1 === 5 || lastValue1 === 6).be.true; - expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1,2,3]); - expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1,2,3]); + expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1, 2, 3]); + expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1, 2, 3]); expect(stateVariables['/x'].stateValues.selectedIndex).eq(lastValue1); expect(stateVariables['/x'].stateValues.animationOn).eq(false); cy.get('#\\/p1').should('have.text', `${lastValue1}, 2, 3`) cy.get('#\\/p2').should('have.text', `${lastValue1}, 2, 3`) - + }) @@ -1608,8 +1608,8 @@ describe('AnimateFromSequence Tag Tests', function () { expect(lastValue2 === 7 || lastValue2 === 8).be.true; - expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1,lastValue2,3]); - expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1,lastValue2,3]); + expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1, lastValue2, 3]); + expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1, lastValue2, 3]); expect(stateVariables['/x'].stateValues.selectedIndex).eq(lastValue2); expect(stateVariables['/x'].stateValues.animationOn).eq(false); @@ -1620,7 +1620,7 @@ describe('AnimateFromSequence Tag Tests', function () { cy.log('Switch to animate index 3 while animating'); - cy.get(`#\\/b`).click().then(()=> { + cy.get(`#\\/b`).click().then(() => { cy.get('#\\/p1').should('have.text', `${lastValue1}, 9, 3`) cy.get('#\\/p2').should('have.text', `${lastValue1}, 9, 3`) cy.get('#\\/p1').should('have.text', `${lastValue1}, 10, 3`) @@ -1653,8 +1653,8 @@ describe('AnimateFromSequence Tag Tests', function () { lastValue2 = stateVariables['/nl'].stateValues.numbers[1]; expect(lastValue2 === 1 || lastValue2 === 2).be.true; - expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1,lastValue2,lastValue3]); - expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1,lastValue2,lastValue3]); + expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1, lastValue2, lastValue3]); + expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1, lastValue2, lastValue3]); expect(stateVariables['/x'].stateValues.selectedIndex).eq(lastValue3); expect(stateVariables['/x'].stateValues.animationOn).eq(false); @@ -1697,8 +1697,8 @@ describe('AnimateFromSequence Tag Tests', function () { cy.window().then(async (win) => { let stateVariables = await win.returnAllStateVariables1(); expect(stateVariables['/x'].stateValues.value).eq(1); - expect(stateVariables['/nl'].stateValues.numbers).eqls([1,2,3]); - expect(stateVariables['/nl2'].stateValues.numbers).eqls([1,2,3]); + expect(stateVariables['/nl'].stateValues.numbers).eqls([1, 2, 3]); + expect(stateVariables['/nl2'].stateValues.numbers).eqls([1, 2, 3]); expect(stateVariables['/x'].stateValues.selectedIndex).eq(1); expect(stateVariables['/x'].stateValues.animationOn).eq(false); }) @@ -1728,14 +1728,14 @@ describe('AnimateFromSequence Tag Tests', function () { lastValue1 = stateVariables['/x'].stateValues.value; expect(lastValue1 === 5 || lastValue1 === 6).be.true; - expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1,2,3]); - expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1,2,3]); + expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1, 2, 3]); + expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1, 2, 3]); expect(stateVariables['/x'].stateValues.selectedIndex).eq(lastValue1); expect(stateVariables['/x'].stateValues.animationOn).eq(false); cy.get('#\\/p1').should('have.text', `${lastValue1}, 2, 3`) cy.get('#\\/p2').should('have.text', `${lastValue1}, 2, 3`) - + }) @@ -1771,8 +1771,8 @@ describe('AnimateFromSequence Tag Tests', function () { expect(lastValue2 === 7 || lastValue2 === 8).be.true; - expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1,lastValue2,3]); - expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1,lastValue2,3]); + expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1, lastValue2, 3]); + expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1, lastValue2, 3]); expect(stateVariables['/x'].stateValues.selectedIndex).eq(lastValue2); expect(stateVariables['/x'].stateValues.animationOn).eq(false); @@ -1783,7 +1783,7 @@ describe('AnimateFromSequence Tag Tests', function () { cy.log('Switch to animate index 3 while animating'); - cy.get(`#\\/b`).click().then(()=> { + cy.get(`#\\/b`).click().then(() => { cy.get('#\\/p1').should('have.text', `${lastValue1}, 9, 3`) cy.get('#\\/p2').should('have.text', `${lastValue1}, 9, 3`) cy.get('#\\/p1').should('have.text', `${lastValue1}, 10, 3`) @@ -1816,8 +1816,8 @@ describe('AnimateFromSequence Tag Tests', function () { lastValue2 = stateVariables['/nl'].stateValues.numbers[1]; expect(lastValue2 === 1 || lastValue2 === 2).be.true; - expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1,lastValue2,lastValue3]); - expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1,lastValue2,lastValue3]); + expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1, lastValue2, lastValue3]); + expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1, lastValue2, lastValue3]); expect(stateVariables['/x'].stateValues.selectedIndex).eq(lastValue3); expect(stateVariables['/x'].stateValues.animationOn).eq(false); @@ -1863,8 +1863,8 @@ describe('AnimateFromSequence Tag Tests', function () { cy.window().then(async (win) => { let stateVariables = await win.returnAllStateVariables1(); expect(stateVariables['/x'].stateValues.value).eq(1); - expect(stateVariables['/nl'].stateValues.numbers).eqls([1,2,3]); - expect(stateVariables['/nl2'].stateValues.numbers).eqls([1,2,3]); + expect(stateVariables['/nl'].stateValues.numbers).eqls([1, 2, 3]); + expect(stateVariables['/nl2'].stateValues.numbers).eqls([1, 2, 3]); expect(stateVariables['/x'].stateValues.selectedIndex).eq(1); expect(stateVariables['/x'].stateValues.animationOn).eq(false); }) @@ -1894,14 +1894,14 @@ describe('AnimateFromSequence Tag Tests', function () { lastValue1 = stateVariables['/x'].stateValues.value; expect(lastValue1 === 5 || lastValue1 === 6).be.true; - expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1,2,3]); - expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1,2,3]); + expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1, 2, 3]); + expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1, 2, 3]); expect(stateVariables['/x'].stateValues.selectedIndex).eq(lastValue1); expect(stateVariables['/x'].stateValues.animationOn).eq(false); cy.get('#\\/p1').should('have.text', `${lastValue1}, 2, 3`) cy.get('#\\/p2').should('have.text', `${lastValue1}, 2, 3`) - + }) @@ -1937,8 +1937,8 @@ describe('AnimateFromSequence Tag Tests', function () { expect(lastValue2 === 7 || lastValue2 === 8).be.true; - expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1,lastValue2,3]); - expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1,lastValue2,3]); + expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1, lastValue2, 3]); + expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1, lastValue2, 3]); expect(stateVariables['/x'].stateValues.selectedIndex).eq(lastValue2); expect(stateVariables['/x'].stateValues.animationOn).eq(false); @@ -1949,7 +1949,7 @@ describe('AnimateFromSequence Tag Tests', function () { cy.log('Switch to animate index 3 while animating'); - cy.get(`#\\/b`).click().then(()=> { + cy.get(`#\\/b`).click().then(() => { cy.get('#\\/p1').should('have.text', `${lastValue1}, 9, 3`) cy.get('#\\/p2').should('have.text', `${lastValue1}, 9, 3`) cy.get('#\\/p1').should('have.text', `${lastValue1}, 10, 3`) @@ -1982,8 +1982,8 @@ describe('AnimateFromSequence Tag Tests', function () { lastValue2 = stateVariables['/nl'].stateValues.numbers[1]; expect(lastValue2 === 1 || lastValue2 === 2).be.true; - expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1,lastValue2,lastValue3]); - expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1,lastValue2,lastValue3]); + expect(stateVariables['/nl'].stateValues.numbers).eqls([lastValue1, lastValue2, lastValue3]); + expect(stateVariables['/nl2'].stateValues.numbers).eqls([lastValue1, lastValue2, lastValue3]); expect(stateVariables['/x'].stateValues.selectedIndex).eq(lastValue3); expect(stateVariables['/x'].stateValues.animationOn).eq(false); @@ -1996,5 +1996,35 @@ describe('AnimateFromSequence Tag Tests', function () { }) + it('animation stops when triggered by its own variable', () => { + cy.window().then(async (win) => { + win.postMessage({ + doenetML: ` + 1 + + + + + + + + `}, "*"); + }); + + cy.get("#\\/isOn").should('have.text', 'true'); + cy.get('#\\/t').should('have.text', '1'); + cy.get('#\\/t').should('have.text', '2'); + cy.get('#\\/t').should('have.text', '3'); + cy.get("#\\/isOn").should('have.text', 'false'); + + cy.wait(500); + + cy.get('#\\/t').should('have.text', '3'); + cy.get("#\\/isOn").should('have.text', 'false'); + + }) + }); diff --git a/src/Core/components/AnimateFromSequence.js b/src/Core/components/AnimateFromSequence.js index cce850fae6..321b57d417 100644 --- a/src/Core/components/AnimateFromSequence.js +++ b/src/Core/components/AnimateFromSequence.js @@ -4,10 +4,6 @@ import me from 'math-expressions'; import { nanoid } from 'nanoid'; export default class AnimateFromSequence extends BaseComponent { - constructor(args) { - super(args); - this.advanceAnimation = this.advanceAnimation.bind(this); - } static componentType = "animateFromSequence"; static rendererType = undefined; @@ -205,7 +201,7 @@ export default class AnimateFromSequence extends BaseComponent { } } else { // if not number, just try to find in sequence - let desiredValue = stateVariablesToUpdate.value; + let desiredValue = desiredStateVariableValues.value; let index = dependencyValues.possibleValues.indexOf(desiredValue); if (index === -1) { return { success: false }; @@ -659,10 +655,12 @@ export default class AnimateFromSequence extends BaseComponent { async advanceAnimation({ previousAnimationId, actionId }) { + let animationOn = await this.stateValues.animationOn; + // especially given delays in posting messages, // it's possible that advanceAnimation is called from // a animationId that was supposed to have been canceled - if (previousAnimationId === this.canceledAnimationId) { + if (previousAnimationId === this.canceledAnimationId || !animationOn) { this.coreFunctions.resolveAction({ actionId }); return; }