diff --git a/packages/doenetml-worker/src/test/assignNames/basicCopy.test.ts b/packages/doenetml-worker/src/test/assignNames/basicCopy.test.ts index 7d576271a..b7b47dd51 100644 --- a/packages/doenetml-worker/src/test/assignNames/basicCopy.test.ts +++ b/packages/doenetml-worker/src/test/assignNames/basicCopy.test.ts @@ -1,13 +1,6 @@ import { describe, expect, it, vi } from "vitest"; import { createTestCore, returnAllStateVariables } from "../utils/test-core"; -import { - movePoint, - updateBooleanInputValue, - updateMathInputValue, - updateTextInputValue, - updateValue, -} from "../utils/actions"; -import Core from "../../Core"; +import { movePoint, updateMathInputValue } from "../utils/actions"; const Mock = vi.fn(); vi.stubGlobal("postMessage", Mock); diff --git a/packages/doenetml-worker/src/test/variants/uniqueVariants.test.ts b/packages/doenetml-worker/src/test/variants/uniqueVariants.test.ts new file mode 100644 index 000000000..de136da39 --- /dev/null +++ b/packages/doenetml-worker/src/test/variants/uniqueVariants.test.ts @@ -0,0 +1,2683 @@ +import { describe, expect, it, vi } from "vitest"; +import { createTestCore, returnAllStateVariables } from "../utils/test-core"; +import { + submitAnswer, + updateMathInputValue, + updateSelectedIndices, + updateTextInputValue, +} from "../utils/actions"; +import { numberToLetters } from "@doenet/utils"; +import me from "math-expressions"; + +const Mock = vi.fn(); +vi.stubGlobal("postMessage", Mock); +vi.mock("hyperformula"); + +describe("Unique variant tests", async () => { + it("single select", async () => { + let values = ["u", "v", "w", "x", "y", "z"]; + let doenetML = ` + + + `; + + // get all values in order and they repeat in next variants + for (let ind = 1; ind <= 18; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/x"].stateValues.value.tree).eq( + values[(ind - 1) % 6], + ); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e", "f"]); + } + }); + + it("single selectFromSequence", async () => { + let doenetML = ` + + + `; + // get all values in order and they repeat in next variants + for (let ind = 1; ind <= 15; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/x"].stateValues.value).eq( + ((ind - 1) % 5) + 1, + ); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e"]); + } + }); + + it("selectFromSequence with excludes", async () => { + let doenetML = ` + + + `; + // get all values in order and they repeat in next variants + for (let ind = 1; ind <= 12; ind++) { + let letters = ["c", "e", "i", "m"]; + + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/x"].stateValues.value).eq( + letters[(ind - 1) % 4], + ); + } + }); + + it("select and selectFromSequence combination", async () => { + let valuesW = ["m", "n"]; + let valuesX = ["x", "y", "z"]; + let valuesY = [2, 3, 4]; + let valuesZ = [3, 7]; + + let values: string[] = []; + for (let w of valuesW) { + for (let x of valuesX) { + for (let y of valuesY) { + for (let z of valuesZ) { + values.push([w, x, y, z].join(",")); + } + } + } + } + let valuesFound: string[] = []; + + let numVariants = + valuesW.length * valuesX.length * valuesY.length * valuesZ.length; + + let wsFound: string[] = [], + xsFound: string[] = [], + ysFound: number[] = [], + zsFound: number[] = []; + + let doenetML = ` + + + + + + + + `; + + // get all values in variants + for (let ind = 1; ind <= numVariants; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newW = stateVariables["/w"].stateValues.value; + let newX = stateVariables["/x"].stateValues.value.tree; + let newY = stateVariables["/y"].stateValues.value; + let newZ = stateVariables["/z"].stateValues.value.tree; + let newValue = [newW, newX, newY, newZ].join(","); + expect(values.includes(newValue)).eq(true); + expect(valuesFound.includes(newValue)).eq(false); + valuesFound.push(newValue); + + if (ind <= 3) { + wsFound.push(newW); + xsFound.push(newX); + ysFound.push(newY); + zsFound.push(newZ); + } + } + + // all individual options selected in first variants + expect(wsFound.slice(0, 2).sort()).eqls(valuesW); + expect(xsFound.sort()).eqls(valuesX); + expect(ysFound.sort()).eqls(valuesY); + expect(zsFound.slice(0, 2).sort()).eqls(valuesZ); + + // values begin to repeat in next variants + for (let ind = numVariants + 1; ind <= numVariants + 15; ind += 3) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newW = stateVariables["/w"].stateValues.value; + let newX = stateVariables["/x"].stateValues.value.tree; + let newY = stateVariables["/y"].stateValues.value; + let newZ = stateVariables["/z"].stateValues.value.tree; + let newValue = [newW, newX, newY, newZ].join(","); + + expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); + } + }); + + it("select multiple", async () => { + let valuesSingle = ["w", "x", "y", "z"]; + let valuesFound: string[] = []; + let values: string[] = []; + for (let x of valuesSingle) { + for (let y of valuesSingle) { + if (y == x) { + continue; + } + for (let z of valuesSingle) { + if (z === x || z === y) { + continue; + } + values.push([x, y, z].join(",")); + } + } + } + + let numVariants = values.length; + + let xsFound: string[] = [], + ysFound: string[] = [], + zsFound: string[] = []; + + let doenetML = ` + + + `; + + // get all values in first variants + for (let ind = 1; ind <= numVariants; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newX = stateVariables["/x"].stateValues.value.tree; + let newY = stateVariables["/y"].stateValues.value.tree; + let newZ = stateVariables["/z"].stateValues.value.tree; + let newValue = [newX, newY, newZ].join(","); + expect(values.includes(newValue)).eq(true); + expect(valuesFound.includes(newValue)).eq(false); + valuesFound.push(newValue); + + if (ind <= 4) { + xsFound.push(newX); + ysFound.push(newY); + zsFound.push(newZ); + } + } + + // all individual options selected in first variants + expect(xsFound.sort()).eqls(valuesSingle); + expect(ysFound.sort()).eqls(valuesSingle); + expect(zsFound.sort()).eqls(valuesSingle); + + // values begin to repeat in next variants + for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newX = stateVariables["/x"].stateValues.value.tree; + let newY = stateVariables["/y"].stateValues.value.tree; + let newZ = stateVariables["/z"].stateValues.value.tree; + let newValue = [newX, newY, newZ].join(","); + + expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); + } + }); + + it("select multiple with replacement", async () => { + let valuesSingle = ["x", "y", "z"]; + let valuesFound: string[] = []; + let values: string[] = []; + for (let x of valuesSingle) { + for (let y of valuesSingle) { + for (let z of valuesSingle) { + values.push([x, y, z].join(",")); + } + } + } + + let numVariants = values.length; + let xsFound: string[] = [], + ysFound: string[] = [], + zsFound: string[] = []; + + let doenetML = ` + + + `; + + // get all values in first variants + for (let ind = 1; ind <= numVariants; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newX = stateVariables["/x"].stateValues.value.tree; + let newY = stateVariables["/y"].stateValues.value.tree; + let newZ = stateVariables["/z"].stateValues.value.tree; + let newValue = [newX, newY, newZ].join(","); + expect(values.includes(newValue)).eq(true); + expect(valuesFound.includes(newValue)).eq(false); + valuesFound.push(newValue); + + if (ind <= 3) { + xsFound.push(newX); + ysFound.push(newY); + zsFound.push(newZ); + } + } + + // all individual options selected in first variants + expect(xsFound.sort()).eqls(valuesSingle); + expect(ysFound.sort()).eqls(valuesSingle); + expect(zsFound.sort()).eqls(valuesSingle); + + // values begin to repeat in next variants + for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newX = stateVariables["/x"].stateValues.value.tree; + let newY = stateVariables["/y"].stateValues.value.tree; + let newZ = stateVariables["/z"].stateValues.value.tree; + let newValue = [newX, newY, newZ].join(","); + + expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); + } + }); + + it("select multiple from sequence", async () => { + let valuesSingle = ["w", "x", "y", "z"]; + let valuesFound: string[] = []; + let values: string[] = []; + for (let x of valuesSingle) { + for (let y of valuesSingle) { + if (y == x) { + continue; + } + for (let z of valuesSingle) { + if (z === x || z === y) { + continue; + } + values.push([x, y, z].join(",")); + } + } + } + + let numVariants = values.length; + let xsFound: string[] = [], + ysFound: string[] = [], + zsFound: string[] = []; + + let doenetML = ` + + + `; + + // get all values in first variants + for (let ind = 1; ind <= numVariants; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newX = stateVariables["/x"].stateValues.value; + let newY = stateVariables["/y"].stateValues.value; + let newZ = stateVariables["/z"].stateValues.value; + let newValue = [newX, newY, newZ].join(","); + expect(values.includes(newValue)).eq(true); + expect(valuesFound.includes(newValue)).eq(false); + valuesFound.push(newValue); + + if (ind <= 4) { + xsFound.push(newX); + ysFound.push(newY); + zsFound.push(newZ); + } + } + + // all individual options selected in first variants + expect(xsFound.sort()).eqls(valuesSingle); + expect(ysFound.sort()).eqls(valuesSingle); + expect(zsFound.sort()).eqls(valuesSingle); + + for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newX = stateVariables["/x"].stateValues.value; + let newY = stateVariables["/y"].stateValues.value; + let newZ = stateVariables["/z"].stateValues.value; + let newValue = [newX, newY, newZ].join(","); + + expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); + } + }); + + it("select multiple from sequence with replacement", async () => { + let valuesSingle = ["x", "y", "z"]; + let valuesFound: string[] = []; + let values: string[] = []; + for (let x of valuesSingle) { + for (let y of valuesSingle) { + for (let z of valuesSingle) { + values.push([x, y, z].join(",")); + } + } + } + + let numVariants = values.length; + let xsFound: string[] = [], + ysFound: string[] = [], + zsFound: string[] = []; + + let doenetML = ` + + + `; + + // get all values in first variants + for (let ind = 1; ind <= numVariants; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newX = stateVariables["/x"].stateValues.value; + let newY = stateVariables["/y"].stateValues.value; + let newZ = stateVariables["/z"].stateValues.value; + let newValue = [newX, newY, newZ].join(","); + expect(values.includes(newValue)).eq(true); + expect(valuesFound.includes(newValue)).eq(false); + valuesFound.push(newValue); + + if (ind <= 3) { + xsFound.push(newX); + ysFound.push(newY); + zsFound.push(newZ); + } + } + + // all individual options selected in first variants + expect(xsFound.sort()).eqls(valuesSingle); + expect(ysFound.sort()).eqls(valuesSingle); + expect(zsFound.sort()).eqls(valuesSingle); + + // values begin to repeat in next variants + for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newX = stateVariables["/x"].stateValues.value; + let newY = stateVariables["/y"].stateValues.value; + let newZ = stateVariables["/z"].stateValues.value; + let newValue = [newX, newY, newZ].join(","); + + expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); + } + }); + + it("limit variants", async () => { + let valuesSingle = ["u", "v", "w", "x", "y", "z"]; + let valuesFound: string[] = []; + let values: string[] = []; + for (let w of valuesSingle) { + for (let x of valuesSingle) { + for (let y of valuesSingle) { + for (let z of valuesSingle) { + values.push([w, x, y, z].join(",")); + } + } + } + } + + let numVariants = 10; + let wsFound: string[] = [], + xsFound: string[] = [], + ysFound: string[] = [], + zsFound: string[] = []; + + let doenetML = ` + + + `; + + // get unique values in first variants + for (let ind = 1; ind <= numVariants; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newW = stateVariables["/w"].stateValues.value; + let newX = stateVariables["/x"].stateValues.value; + let newY = stateVariables["/y"].stateValues.value; + let newZ = stateVariables["/z"].stateValues.value; + let newValue = [newW, newX, newY, newZ].join(","); + expect(values.includes(newValue)).eq(true); + expect(valuesFound.includes(newValue)).eq(false); + valuesFound.push(newValue); + + if (ind <= 6) { + wsFound.push(newW); + xsFound.push(newX); + ysFound.push(newY); + zsFound.push(newZ); + } + } + + // all individual options selected in first variants + expect(wsFound.sort()).eqls(valuesSingle); + expect(xsFound.sort()).eqls(valuesSingle); + expect(ysFound.sort()).eqls(valuesSingle); + expect(zsFound.sort()).eqls(valuesSingle); + + // values repeat in next variants + for (let ind = numVariants + 1; ind <= 2 * numVariants + 3; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + // to wait for page to load + + let stateVariables = await returnAllStateVariables(core); + let newW = stateVariables["/w"].stateValues.value; + let newX = stateVariables["/x"].stateValues.value; + let newY = stateVariables["/y"].stateValues.value; + let newZ = stateVariables["/z"].stateValues.value; + let newValue = [newW, newX, newY, newZ].join(","); + + expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); + } + }); + + it("selects of selectFromSequence", async () => { + let valuesFound: number[] = []; + let values = [1, 2, 101, 102, 103, 201, 202, 203, 204]; + let numVariants = values.length; + + let doenetML = ` + + + `; + + // get all values in first variants + for (let ind = 1; ind <= numVariants; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newValue = stateVariables["/x"].stateValues.value; + expect(values.includes(newValue)).eq(true); + expect(valuesFound.includes(newValue)).eq(false); + valuesFound.push(newValue); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e", "f", "g", "h", "i"]); + + if (ind === 3) { + // all individual groups selected in first variants + expect(valuesFound.some((x) => x <= 2)).eq(true); + expect(valuesFound.some((x) => x >= 101 && x <= 103)).eq(true); + expect(valuesFound.some((x) => x >= 201 && x <= 204)).eq(true); + } + + if (ind === 6) { + // all individual groups selected twice in first variants + expect( + valuesFound.reduce((a, c) => a + (c <= 2 ? 1 : 0), 0), + ).eq(2); + expect( + valuesFound.reduce( + (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), + 0, + ), + ).eq(2); + expect( + valuesFound.reduce( + (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), + 0, + ), + ).eq(2); + } + + if (ind === 8) { + // most individual groups selected three times in first variants + expect( + valuesFound.reduce((a, c) => a + (c <= 2 ? 1 : 0), 0), + ).eq(2); + expect( + valuesFound.reduce( + (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), + 0, + ), + ).eq(3); + expect( + valuesFound.reduce( + (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), + 0, + ), + ).eq(3); + } + } + + // values repeat in next variants + for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newValue = stateVariables["/x"].stateValues.value; + expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); + } + }); + + it("selects of selects", async () => { + let valuesFound: number[] = []; + let values = [1, 2, 101, 102, 103, 201, 202, 203, 204]; + let numVariants = values.length; + + let doenetML = ` + + 1 2 + + + + + `; + // get all values in first variants + for (let ind = 1; ind <= numVariants; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newValue = stateVariables["/x"].stateValues.value.tree; + expect(values.includes(newValue)).eq(true); + expect(valuesFound.includes(newValue)).eq(false); + valuesFound.push(newValue); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e", "f", "g", "h", "i"]); + + if (ind === 3) { + // all individual groups selected in first variants + expect(valuesFound.some((x) => x <= 2)).eq(true); + expect(valuesFound.some((x) => x >= 101 && x <= 103)).eq(true); + expect(valuesFound.some((x) => x >= 201 && x <= 204)).eq(true); + } + + if (ind === 6) { + // all individual groups selected twice in first variants + expect( + valuesFound.reduce((a, c) => a + (c <= 2 ? 1 : 0), 0), + ).eq(2); + expect( + valuesFound.reduce( + (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), + 0, + ), + ).eq(2); + expect( + valuesFound.reduce( + (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), + 0, + ), + ).eq(2); + } + + if (ind === 8) { + // most individual groups selected three times in first variants + expect( + valuesFound.reduce((a, c) => a + (c <= 2 ? 1 : 0), 0), + ).eq(2); + expect( + valuesFound.reduce( + (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), + 0, + ), + ).eq(3); + expect( + valuesFound.reduce( + (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), + 0, + ), + ).eq(3); + } + } + + // values repeat in next variants + for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newValue = stateVariables["/x"].stateValues.value.tree; + expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); + } + }); + + it("selects of paragraphs of selects/selectFromSequence", async () => { + let valuesFound: number[] = []; + let values = [1, 2, 101, 102, 103, 201, 202, 203, 204]; + let numVariants = values.length; + + let doenetML = ` + + 1 2

+ + + + + `; + // get all values in first variants + for (let ind = 1; ind <= numVariants; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newValue = stateVariables["/x/n"].stateValues.value; + if (newValue.tree !== undefined) { + newValue = newValue.tree; + } + expect(values.includes(newValue)).eq(true); + expect(valuesFound.includes(newValue)).eq(false); + valuesFound.push(newValue); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e", "f", "g", "h", "i"]); + + if (ind === 3) { + // all individual groups selected in first variants + expect(valuesFound.some((x) => x <= 2)).eq(true); + expect(valuesFound.some((x) => x >= 101 && x <= 103)).eq(true); + expect(valuesFound.some((x) => x >= 201 && x <= 204)).eq(true); + } + + if (ind === 6) { + // all individual groups selected twice in first variants + expect( + valuesFound.reduce((a, c) => a + (c <= 2 ? 1 : 0), 0), + ).eq(2); + expect( + valuesFound.reduce( + (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), + 0, + ), + ).eq(2); + expect( + valuesFound.reduce( + (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), + 0, + ), + ).eq(2); + } + + if (ind === 8) { + // most individual groups selected three times in first variants + expect( + valuesFound.reduce((a, c) => a + (c <= 2 ? 1 : 0), 0), + ).eq(2); + expect( + valuesFound.reduce( + (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), + 0, + ), + ).eq(3); + expect( + valuesFound.reduce( + (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), + 0, + ), + ).eq(3); + } + } + + // values repeat in next variants + for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newValue = stateVariables["/x/n"].stateValues.value; + if (newValue.tree !== undefined) { + newValue = newValue.tree; + } + expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); + } + }); + + it("selects of selects, select multiple", async () => { + let valuesFound: string[] = []; + let valuesSingle = [1, 2, 101, 102, 103, 201, 202, 203, 204]; + let values: string[] = []; + for (let x of valuesSingle) { + for (let y of valuesSingle) { + if (Math.abs(y - x) > 5) { + values.push([x, y].join(",")); + } + } + } + let numVariants = values.length; + + let doenetML = ` + + + 1 2 + + + + + + `; + + // get unique values in first variants + for (let ind = 1; ind <= 20; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newX = stateVariables["/x"].stateValues.value.tree; + let newY = stateVariables["/y"].stateValues.value.tree; + let newValue = [newX, newY].join(","); + expect(values.includes(newValue)).eq(true); + expect(valuesFound.includes(newValue)).eq(false); + valuesFound.push(newValue); + } + + // values repeat in next variants + for (let ind = numVariants + 1; ind <= numVariants + 20; ind += 5) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let newX = stateVariables["/x"].stateValues.value.tree; + let newY = stateVariables["/y"].stateValues.value.tree; + let newValue = [newX, newY].join(","); + expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); + } + + // selects all individual groups equally in first variants + let valuesFound1: number[] = []; + let valuesFound2: number[] = []; + for (let pass = 0; pass < 12; pass++) { + for (let ind = pass * 3 + 1; ind <= (pass + 1) * 3; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + valuesFound1.push(stateVariables["/x"].stateValues.value.tree); + valuesFound2.push(stateVariables["/y"].stateValues.value.tree); + } + expect(valuesFound1.reduce((a, c) => a + (c <= 2 ? 1 : 0), 0)).eq( + pass + 1, + ); + expect( + valuesFound1.reduce( + (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), + 0, + ), + ).eq(pass + 1); + expect( + valuesFound1.reduce( + (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), + 0, + ), + ).eq(pass + 1); + expect(valuesFound2.reduce((a, c) => a + (c <= 2 ? 1 : 0), 0)).eq( + pass + 1, + ); + expect( + valuesFound2.reduce( + (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), + 0, + ), + ).eq(pass + 1); + expect( + valuesFound2.reduce( + (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), + 0, + ), + ).eq(pass + 1); + } + }); + + it("deeper nesting of selects/selectFromSequence", async () => { + let doenetML = ` + + + + + + +

+ + + + + + `; + + let valuesFound: string[] = []; + + let colorsA = [ + "red", + "orange", + "yellow", + "magenta", + "maroon", + "fuchsia", + "scarlet", + ]; + let colorsB = ["green", "chartreuse", "turquoise"]; + let colorsC = ["white", "black"]; + let allColors = [...colorsA, ...colorsB, ...colorsC]; + + let letters = [...Array(26)].map((_, i) => + String.fromCharCode("a".charCodeAt(0) + i), + ); + + let variables = ["u", "v", "w", "x", "y", "z"]; + + let categories = [ + "Favorite color:", + "Selected number:", + "Chosen letter:", + "Variable:", + ]; + + let numVariants = 24; + + let colorsFound: string[] = []; + let numbersFound: number[] = []; + let lettersFound: string[] = []; + let variablesFound: string[] = []; + let categoriesFound: string[] = []; + + // get all values in first variants + for (let ind = 1; ind <= numVariants; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let category = stateVariables["/p"].activeChildren[0].trim(); + expect(categories.includes(category)).eq(true); + + let component = + stateVariables[ + stateVariables["/p"].activeChildren.filter( + (x) => x.componentName, + )[0].componentName + ]; + let newValue = component.stateValues.value; + if (category === categories[0]) { + expect(allColors.includes(newValue)).eq(true); + colorsFound.push(newValue); + } else if (category === categories[1]) { + let validNum = + Number.isInteger(newValue) && + ((newValue >= 1000 && newValue <= 2000) || + (newValue >= -1000 && newValue <= -900)); + expect(validNum).eq(true); + numbersFound.push(newValue); + } else if (category === categories[2]) { + expect(letters.includes(newValue)).eq(true); + lettersFound.push(newValue); + } else { + newValue = newValue.tree; + expect(variables.includes(newValue)).eq(true); + variablesFound.push(newValue); + } + + let combinedValue = [category, newValue].join(","); + + expect(valuesFound.includes(combinedValue)).eq(false); + valuesFound.push(combinedValue); + + categoriesFound.push(category); + + if (ind === 4) { + // all individual groups selected in first variants + for (let ind = 0; ind < 4; ind++) { + expect(categoriesFound.includes(categories[ind])).eq(true); + } + } + + if (ind === 8) { + // all individual groups selected twice in first variants + for (let ind = 0; ind < 4; ind++) { + expect( + categoriesFound.slice(4, 8).includes(categories[ind]), + ).eq(true); + } + } + } + + // the 24 values are distributed 6 to each category and evenly distributed across subcategories + let colorsFoundSet = new Set(colorsFound); + expect(colorsFoundSet.size).eq(6); + expect( + colorsA.reduce((a, c) => a + (colorsFoundSet.has(c) ? 1 : 0), 0), + ).eq(2); + expect( + colorsB.reduce((a, c) => a + (colorsFoundSet.has(c) ? 1 : 0), 0), + ).eq(2); + expect( + colorsC.reduce((a, c) => a + (colorsFoundSet.has(c) ? 1 : 0), 0), + ).eq(2); + + expect(numbersFound.reduce((a, c) => a + (c > 0 ? 1 : 0), 0)).eq(3); + expect(numbersFound.reduce((a, c) => a + (c < 0 ? 1 : 0), 0)).eq(3); + + expect(lettersFound.length).eq(6); + expect(variablesFound.length).eq(6); + + expect(variablesFound.sort()).eqls(variables); + + // values repeat in next variants + for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let category = stateVariables["/p"].activeChildren[0].trim(); + let component = + stateVariables[ + stateVariables["/p"].activeChildren.filter( + (x) => x.componentName, + )[0].componentName + ]; + let newValue = component.stateValues.value; + if (newValue.tree !== undefined) { + newValue = newValue.tree; + } + let combinedValue = [category, newValue].join(","); + expect(combinedValue).eq(valuesFound[(ind - 1) % numVariants]); + } + }); + + it("select problems of selects/selectFromSequence", async () => { + let doenetML = ` + + + + + +

Enter the color $(p/color): $(p/color)

+ + + + + +

Enter the word $(p/word): $(p/word)

+ + + + + `; + + let valuesFound: string[] = []; + + let colorsA = [ + "red", + "orange", + "yellow", + "magenta", + "maroon", + "fuchsia", + "scarlet", + ]; + let colorsB = ["green", "chartreuse", "turquoise"]; + let allColors = [...colorsA, ...colorsB]; + + let wordsA = ["run", "walk", "jump", "skip"]; + let wordsB = [ + "soft", + "scary", + "large", + "empty", + "residual", + "limitless", + ]; + let allWords = [...wordsA, ...wordsB]; + + let letters = [...Array(26)].map((_, i) => + String.fromCharCode("a".charCodeAt(0) + i), + ); + + let categories = ["Favorite color", "Selected word", "Chosen letter"]; + + let numVariants = 6; + + let categoriesFound: string[] = []; + let colorsFound: string[] = []; + let wordsFound: string[] = []; + let lettersFound: string[] = []; + + // get all values in first variants + for (let ind = 1; ind <= numVariants; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + + let textinputName = + stateVariables[`/problem/ans`].stateValues.inputChildren[0] + .componentName; + let category = stateVariables["/problem"].stateValues.title; + expect(categories.includes(category)).eq(true); + + let component = + stateVariables[ + stateVariables[ + stateVariables["/problem"].activeChildren.filter( + (x) => x.componentName, + )[1].componentName + ].activeChildren[1].componentName + ]; + let newValue = component.stateValues.value; + if (category === categories[0]) { + expect(allColors.includes(newValue)).eq(true); + colorsFound.push(newValue); + } else if (category === categories[1]) { + expect(allWords.includes(newValue)).eq(true); + wordsFound.push(newValue); + } else if (category === categories[2]) { + expect(letters.includes(newValue)).eq(true); + lettersFound.push(newValue); + } + + let combinedValue = [category, newValue].join(","); + + expect(valuesFound.includes(combinedValue)).eq(false); + valuesFound.push(combinedValue); + + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e", "f"]); + + categoriesFound.push(category); + + if (ind === 3) { + // all individual groups selected in first variants + for (let ind = 0; ind < 3; ind++) { + expect(categoriesFound.includes(categories[ind])).eq(true); + } + } + + if (ind === 6) { + // all individual groups selected twice in first variants + for (let ind = 0; ind < 3; ind++) { + expect( + categoriesFound.slice(3).includes(categories[ind]), + ).eq(true); + } + } + + await updateTextInputValue({ + text: `${newValue}`, + name: textinputName, + core, + }); + await submitAnswer({ name: `/problem/ans`, core }); + stateVariables = await returnAllStateVariables(core); + expect( + stateVariables["/problem/ans"].stateValues.creditAchieved, + ).eq(1); + expect( + stateVariables["/problem/ans"].stateValues.submittedResponses, + ).eqls([newValue]); + expect(stateVariables[textinputName].stateValues.value).eq( + newValue, + ); + + await updateTextInputValue({ + text: `${newValue}X`, + name: textinputName, + core, + }); + await submitAnswer({ name: `/problem/ans`, core }); + + stateVariables = await returnAllStateVariables(core); + expect( + stateVariables["/problem/ans"].stateValues.creditAchieved, + ).eq(0); + expect( + stateVariables["/problem/ans"].stateValues.submittedResponses, + ).eqls([newValue + "X"]); + expect(stateVariables[textinputName].stateValues.value).eq( + newValue + "X", + ); + + await updateTextInputValue({ + text: `${newValue}`, + name: textinputName, + core, + }); + await submitAnswer({ name: `/problem/ans`, core }); + + stateVariables = await returnAllStateVariables(core); + expect( + stateVariables["/problem/ans"].stateValues.creditAchieved, + ).eq(1); + expect( + stateVariables["/problem/ans"].stateValues.submittedResponses, + ).eqls([newValue]); + expect(stateVariables[textinputName].stateValues.value).eq( + newValue, + ); + } + + let colorsFoundSet = new Set(colorsFound); + expect(colorsFoundSet.size).eq(2); + expect( + colorsA.reduce((a, c) => a + (colorsFoundSet.has(c) ? 1 : 0), 0), + ).eq(1); + expect( + colorsB.reduce((a, c) => a + (colorsFoundSet.has(c) ? 1 : 0), 0), + ).eq(1); + + let wordsFoundSet = new Set(wordsFound); + expect(wordsFoundSet.size).eq(2); + expect( + wordsA.reduce((a, c) => a + (wordsFoundSet.has(c) ? 1 : 0), 0), + ).eq(1); + expect( + wordsB.reduce((a, c) => a + (wordsFoundSet.has(c) ? 1 : 0), 0), + ).eq(1); + + // values repeat in next variants + for (let ind = numVariants + 1; ind <= numVariants + 6; ind += 2) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let category = stateVariables["/problem"].stateValues.title; + let component = + stateVariables[ + stateVariables[ + stateVariables["/problem"].activeChildren.filter( + (x) => x.componentName, + )[1].componentName + ].activeChildren[1].componentName + ]; + let newValue = component.stateValues.value; + let combinedValue = [category, newValue].join(","); + expect(combinedValue).eq(valuesFound[(ind - 1) % numVariants]); + } + }); + + it("can get unique with map without variants", async () => { + let doenetML = ` + + + + + + + + +

N:

+ `; + + // get all values in order and they repeat in next variants + for (let ind = 1; ind <= 4; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/x"].stateValues.value).eq( + ((ind - 1) % 3) + 1, + ); + expect(stateVariables["/p1"].stateValues.text).eq("letter: a"); + expect(stateVariables["/p2"]).be.undefined; + + await updateMathInputValue({ latex: "3", name: "/n", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/p1"].stateValues.text).eq("letter: a"); + expect(stateVariables["/p2"].stateValues.text).eq("letter: b"); + expect(stateVariables["/p3"].stateValues.text).eq("letter: c"); + + expect(stateVariables["/x"].stateValues.value).eq( + ((ind - 1) % 3) + 1, + ); + expect( + stateVariables[ + stateVariables["/p1"].activeChildren[1].componentName + ].stateValues.value, + ).eq("a"); + expect( + stateVariables[ + stateVariables["/p2"].activeChildren[1].componentName + ].stateValues.value, + ).eq("b"); + expect( + stateVariables[ + stateVariables["/p3"].activeChildren[1].componentName + ].stateValues.value, + ).eq("c"); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c"]); + + await updateMathInputValue({ latex: "4", name: "/n", core }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/p1"].stateValues.text).eq("letter: a"); + expect(stateVariables["/p2"].stateValues.text).eq("letter: b"); + expect(stateVariables["/p3"].stateValues.text).eq("letter: c"); + expect(stateVariables["/p4"].stateValues.text).eq("letter: d"); + } + }); + + async function test_shuffled_choice_input( + doenetML: string, + insiderAnswer = false, + ) { + let ordersFound: string[] = []; + let choices = ["red", "blue", "green"]; + + // get all orders in first 6 variants + for (let ind = 1; ind <= 6; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + let stateVariables = await returnAllStateVariables(core); + + let ciName = "/ci"; + if (insiderAnswer) { + ciName = + stateVariables["/ans"].stateValues.inputChildren[0] + .componentName; + } + + let choiceOrder = stateVariables[ciName].stateValues.choiceOrder; + let selectedOrder = choiceOrder.join(","); + expect(ordersFound.includes(selectedOrder)).eq(false); + ordersFound.push(selectedOrder); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e", "f"]); + + for (let i = 0; i < 3; i++) { + await updateSelectedIndices({ + name: ciName, + selectedIndices: [i + 1], + core, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables[ciName].stateValues.selectedValues).eqls([ + choices[choiceOrder[i] - 1], + ]); + } + + await updateSelectedIndices({ + name: ciName, + selectedIndices: [1], + core, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables[ciName].stateValues.selectedValues).eqls([ + choices[choiceOrder[0] - 1], + ]); + } + + // 7th variant repeats first order + let ind = 7; + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let ciName = "/ci"; + if (insiderAnswer) { + ciName = + stateVariables["/ans"].stateValues.inputChildren[0] + .componentName; + } + let choiceOrder = stateVariables[ciName].stateValues.choiceOrder; + let selectedOrder = choiceOrder.join(","); + expect(selectedOrder).eq(ordersFound[0]); + } + + it("single shuffled choiceInput", async () => { + let doenetML = ` + + + red + blue + green + + + `; + + await test_shuffled_choice_input(doenetML); + }); + + it("single shuffled choiceInput, choices copied in", async () => { + let doenetML = ` + + red + + blue + green + + + + + + + `; + + await test_shuffled_choice_input(doenetML); + }); + + it("single shuffled choiceInput sugared inside answer", async () => { + let doenetML = ` + + red + blue + green + + + `; + + await test_shuffled_choice_input(doenetML, true); + }); + + it("shuffled choiceInput with selectFromSequence in choices", async () => { + let doenetML = ` + + + + + + `; + + let selectionsFound: string[] = []; + + // get all options in first 8 variants + for (let ind = 1; ind <= 8; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let choiceOrder = stateVariables["/ci"].stateValues.choiceOrder; + let n = stateVariables["/n"].stateValues.value; + let l = stateVariables["/l"].stateValues.value; + let choices = [n.toString(), l]; + let selectedOption = [...choiceOrder, ...choices].join(","); + expect(selectionsFound.includes(selectedOption)).eq(false); + selectionsFound.push(selectedOption); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e", "f", "g", "h"]); + + for (let i = 0; i < 2; i++) { + await updateSelectedIndices({ + name: "/ci", + selectedIndices: [i + 1], + core, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/ci"].stateValues.selectedValues).eqls([ + choices[choiceOrder[i] - 1], + ]); + } + + await updateSelectedIndices({ + name: "/ci", + selectedIndices: [1], + core, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/ci"].stateValues.selectedValues).eqls([ + choices[choiceOrder[0] - 1], + ]); + } + + let ind = 9; + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let choiceOrder = stateVariables["/ci"].stateValues.choiceOrder; + let n = stateVariables["/n"].stateValues.value; + let l = stateVariables["/l"].stateValues.value; + let choices = [n.toString(), l]; + let selectedOption = [...choiceOrder, ...choices].join(","); + expect(selectedOption).eq(selectionsFound[0]); + }); + + async function test_shuffle(doenetML: string) { + let ordersFound: string[] = []; + let colors = ["red", "blue", "green"]; + + // get all orders in first 6 variants + for (let ind = 1; ind <= 6; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let componentOrder = + stateVariables["/sh"].stateValues.componentOrder; + expect([...componentOrder].sort()).eqls([1, 2, 3]); + + let selectedOrder = componentOrder.join(","); + expect(ordersFound.includes(selectedOrder)).eq(false); + ordersFound.push(selectedOrder); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e", "f"]); + + expect(stateVariables["/pList"].stateValues.text).eq( + componentOrder.map((x) => colors[x - 1]).join(", "), + ); + } + + // 7th variant repeats first order + let ind = 7; + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let componentOrder = stateVariables["/sh"].stateValues.componentOrder; + let selectedOrder = componentOrder.join(","); + expect(selectedOrder).eq(ordersFound[0]); + + expect(stateVariables["/pList"].stateValues.text).eq( + componentOrder.map((x) => colors[x - 1]).join(", "), + ); + } + + it("shuffle", async () => { + let doenetML = ` + +

+ red + blue + green +

+ + `; + + await test_shuffle(doenetML); + }); + + it("shuffle, copy in components", async () => { + let doenetML = ` + + red + + blue + green + +

+ + +

+ + `; + + await test_shuffle(doenetML); + }); + + async function test_document_problem_unique({ + doenetML, + mOptions = [], + nOptions = [], + }: { + doenetML: string; + mOptions?: number[]; + nOptions?: number[]; + }) { + // Note: mOptions must be length 2 if exists + // nOptions must be length 3 if exists + + // get all 6 options and then they repeat + for (let ind = 1; ind <= 8; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + + let mathInputName = + stateVariables["/ans1"].stateValues.inputChildren[0] + .componentName; + let mathInput2Name = + stateVariables["/ans2"].stateValues.inputChildren[0] + .componentName; + + let m = mOptions[(ind - 1) % 2]; + let n = nOptions[(ind - 1) % 3]; + if (m === undefined) { + m = stateVariables["/m"].stateValues.value; + mOptions.push(m); + } else { + expect(stateVariables["/m"].stateValues.value).eq(m); + } + if (n === undefined) { + n = stateVariables["/n"].stateValues.value; + nOptions.push(n); + } else { + expect(stateVariables["/n"].stateValues.value).eq(n); + } + + console.log({ m, n, mOptions, nOptions }); + + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e", "f"]); + + await updateMathInputValue({ + latex: `${m}`, + name: mathInputName, + core, + }); + await submitAnswer({ name: "/ans1", core }); + await updateMathInputValue({ + latex: `${n}`, + name: mathInput2Name, + core, + }); + await submitAnswer({ name: "/ans2", core }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/ans1"].stateValues.creditAchieved).eq(1); + expect(stateVariables["/ans2"].stateValues.creditAchieved).eq(1); + expect( + stateVariables["/ans1"].stateValues.submittedResponses[0].tree, + ).eq(m); + expect( + stateVariables["/ans2"].stateValues.submittedResponses[0].tree, + ).eq(n); + + await updateMathInputValue({ + latex: `${m}1`, + name: mathInputName, + core, + }); + await submitAnswer({ name: "/ans1", core }); + await updateMathInputValue({ + latex: `${n}1`, + name: mathInput2Name, + core, + }); + await submitAnswer({ name: "/ans2", core }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/ans1"].stateValues.creditAchieved).eq(0); + expect(stateVariables["/ans2"].stateValues.creditAchieved).eq(0); + + expect( + stateVariables["/ans1"].stateValues.submittedResponses[0].tree, + ).eq(m * 10 + 1); + expect( + stateVariables["/ans2"].stateValues.submittedResponses[0].tree, + ).eq(n * 10 + 1); + + await updateMathInputValue({ + latex: `${m}`, + name: mathInputName, + core, + }); + await submitAnswer({ name: "/ans1", core }); + await updateMathInputValue({ + latex: `${n}`, + name: mathInput2Name, + core, + }); + await submitAnswer({ name: "/ans2", core }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/ans1"].stateValues.creditAchieved).eq(1); + expect(stateVariables["/ans2"].stateValues.creditAchieved).eq(1); + expect( + stateVariables["/ans1"].stateValues.submittedResponses[0].tree, + ).eq(m); + expect( + stateVariables["/ans2"].stateValues.submittedResponses[0].tree, + ).eq(n); + } + } + + it("document and problems with unique variants", async () => { + let doenetML = ` + + + +

Enter : + $m +

+
+ + +

Enter : + $n +

+
+ `; + + await test_document_problem_unique({ + doenetML, + mOptions: [1, 2], + nOptions: [3, 4, 5], + }); + }); + + it("document and problems with unique variants, even without specifying in document", async () => { + let doenetML = ` + + +

Enter : + $m +

+
+ + +

Enter : + $n +

+
+ `; + + await test_document_problem_unique({ + doenetML, + mOptions: [1, 2], + nOptions: [3, 4, 5], + }); + }); + + it("document and problems with unique variants, even without specifying in document or problem", async () => { + let doenetML = ` + +

Enter : + $m +

+
+ +

Enter : + $n +

+
+ `; + + await test_document_problem_unique({ + doenetML, + mOptions: [1, 2], + nOptions: [3, 4, 5], + }); + }); + + it("document with unique variants, from problems without unique variants", async () => { + let doenetML = ` + + + +

Enter : + $m +

+
+ + +

Enter : + $n +

+
+ `; + + await test_document_problem_unique({ doenetML }); + }); + + it("document with unique variants, from problems without unique variants, even without specifying unique", async () => { + let doenetML = ` + + +

Enter : + $m +

+
+ + +

Enter : + $n +

+
+ `; + + await test_document_problem_unique({ doenetML }); + }); + + it("document inherits variants from single problem with unique variants", async () => { + let doenetML = ` + + +

Enter : + $m +

+
+ `; + + // get all 3 options and then they repeat + for (let ind = 1; ind <= 4; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let m = ((ind - 1) % 3) + 5; + + let stateVariables = await returnAllStateVariables(core); + + let mathInputName = + stateVariables["/ans"].stateValues.inputChildren[0] + .componentName; + + expect(stateVariables["/m"].stateValues.value).eq(m); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants, + ).eqls(["five", "six", "seven"]); + expect( + stateVariables["/_document1"].sharedParameters.variantName, + ).eq(["five", "six", "seven"][(ind - 1) % 3]); + + await updateMathInputValue({ + latex: `${m}`, + name: mathInputName, + core, + }); + await submitAnswer({ name: "/ans", core }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/ans"].stateValues.creditAchieved).eq(1); + expect( + stateVariables["/ans"].stateValues.submittedResponses[0].tree, + ).eq(m); + + await updateMathInputValue({ + latex: `${m}1`, + name: mathInputName, + core, + }); + await submitAnswer({ name: "/ans", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/ans"].stateValues.creditAchieved).eq(0); + expect( + stateVariables["/ans"].stateValues.submittedResponses[0].tree, + ).eq(m * 10 + 1); + + await updateMathInputValue({ + latex: `${m}`, + name: mathInputName, + core, + }); + await submitAnswer({ name: "/ans", core }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/ans"].stateValues.creditAchieved).eq(1); + expect( + stateVariables["/ans"].stateValues.submittedResponses[0].tree, + ).eq(m); + } + }); + + it("no variant control, 1 unique variant", async () => { + let core = await createTestCore({ doenetML: "hello" }); + + let stateVariables = await returnAllStateVariables(core); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls(["a"]); + }); + + it("no variant control, single select", async () => { + let doenetML = ``; + let values = ["u", "v", "w"]; + + // get all values in order and they repeat in next variants + for (let ind = 1; ind <= 4; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/x"].stateValues.value.tree).eq( + values[(ind - 1) % 3], + ); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c"]); + } + }); + + it("no variant control, select and selectFromSequence", async () => { + let doenetML = ` + + + `; + let values = ["u", "v", "w"]; + + // get first values in order + for (let ind = 1; ind <= 3; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/x"].stateValues.value.tree).eq( + values[ind - 1], + ); + expect(stateVariables["/n"].stateValues.value).eq(ind); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants.length, + ).eq(30); + } + }); + + it("no variant control, 100 is still unique variants", async () => { + let doenetML = ` + + `; + // get first values in order + for (let ind = 1; ind <= 5; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).eq(ind); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants.length, + ).eq(100); + } + }); + + it("no variant control, 101 is not unique variants", async () => { + let doenetML = ` + + `; + let foundOneNotInOrder = false; + + // don't get first values in order + for (let ind = 1; ind <= 3; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + if (stateVariables["/n"].stateValues.value !== ind) { + foundOneNotInOrder = true; + } + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants.length, + ).eq(100); + } + + expect(foundOneNotInOrder).eq(true); + }); + + it("no variant control, problem with 3 selects", async () => { + // Catch bug in enumerateCombinations + // where was indirectly overwriting numVariantsByDescendant + + let doenetML = ` + + + + + + `; + + let values = [135, 246, 145, 236, 136, 245, 146, 235]; + + // get each value exactly one, in order corresponding to above list + let valuesFound: number[] = []; + for (let ind = 1; ind <= 8; ind++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: ind, + }); + + let stateVariables = await returnAllStateVariables(core); + let a = stateVariables["/a"].stateValues.value; + let b = stateVariables["/b"].stateValues.value; + let c = stateVariables["/c"].stateValues.value; + + let val = a * 100 + b * 10 + c; + valuesFound.push(val); + expect( + stateVariables["/_document1"].sharedParameters + .allPossibleVariants.length, + ).eq(8); + } + + expect(valuesFound).eqls(values); + }); + + async function test_variants_include_exclude({ + createDoenetML, + variantsFromProblem = false, + documentAndProblemVariantsDiffer = false, + }: { + createDoenetML: ({ + include, + exclude, + }?: { + include?: string[]; + exclude?: string[]; + }) => string; + variantsFromProblem?: boolean; + documentAndProblemVariantsDiffer?: boolean; + }) { + // get two variants with no include/exclude + + let core = await createTestCore({ + doenetML: createDoenetML(), + requestedVariantIndex: 2, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).eq(2); + expect(stateVariables["/_document1"].sharedParameters.variantSeed).eq( + "2", + ); + expect(stateVariables["/_document1"].sharedParameters.variantIndex).eq( + 2, + ); + expect(stateVariables["/_document1"].sharedParameters.variantName).eq( + "b", + ); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]); + + if (variantsFromProblem) { + expect(stateVariables["/problem1"].sharedParameters.variantSeed).eq( + "2", + ); + expect( + stateVariables["/problem1"].sharedParameters.variantIndex, + ).eq(2); + expect(stateVariables["/problem1"].sharedParameters.variantName).eq( + "b", + ); + expect( + stateVariables["/problem1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]); + } + + core = await createTestCore({ + doenetML: createDoenetML(), + requestedVariantIndex: 5, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).eq(5); + expect(stateVariables["/_document1"].sharedParameters.variantSeed).eq( + "5", + ); + expect(stateVariables["/_document1"].sharedParameters.variantIndex).eq( + 5, + ); + expect(stateVariables["/_document1"].sharedParameters.variantName).eq( + "e", + ); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]); + + if (variantsFromProblem) { + expect(stateVariables["/problem1"].sharedParameters.variantSeed).eq( + "5", + ); + expect( + stateVariables["/problem1"].sharedParameters.variantIndex, + ).eq(5); + expect(stateVariables["/problem1"].sharedParameters.variantName).eq( + "e", + ); + expect( + stateVariables["/problem1"].sharedParameters + .allPossibleVariants, + ).eqls(["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]); + } + + // get same variants when add variantsToInclude + + core = await createTestCore({ + doenetML: createDoenetML({ include: ["b", "e"] }), + requestedVariantIndex: 1, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).eq(2); + expect(stateVariables["/_document1"].sharedParameters.variantSeed).eq( + variantsFromProblem ? "1" : "2", + ); + expect(stateVariables["/_document1"].sharedParameters.variantIndex).eq( + 1, + ); + expect(stateVariables["/_document1"].sharedParameters.variantName).eq( + documentAndProblemVariantsDiffer ? "a" : "b", + ); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls(documentAndProblemVariantsDiffer ? ["a", "b"] : ["b", "e"]); + if (variantsFromProblem) { + expect(stateVariables["/problem1"].sharedParameters.variantSeed).eq( + "2", + ); + expect( + stateVariables["/problem1"].sharedParameters.variantIndex, + ).eq(1); + expect(stateVariables["/problem1"].sharedParameters.variantName).eq( + "b", + ); + expect( + stateVariables["/problem1"].sharedParameters + .allPossibleVariants, + ).eqls(["b", "e"]); + } + + core = await createTestCore({ + doenetML: createDoenetML({ include: ["b", "e"] }), + requestedVariantIndex: 2, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).eq(5); + expect(stateVariables["/_document1"].sharedParameters.variantSeed).eq( + variantsFromProblem ? "2" : "5", + ); + expect(stateVariables["/_document1"].sharedParameters.variantIndex).eq( + 2, + ); + expect(stateVariables["/_document1"].sharedParameters.variantName).eq( + documentAndProblemVariantsDiffer ? "b" : "e", + ); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls(documentAndProblemVariantsDiffer ? ["a", "b"] : ["b", "e"]); + if (variantsFromProblem) { + expect(stateVariables["/problem1"].sharedParameters.variantSeed).eq( + "5", + ); + expect( + stateVariables["/problem1"].sharedParameters.variantIndex, + ).eq(2); + expect(stateVariables["/problem1"].sharedParameters.variantName).eq( + "e", + ); + expect( + stateVariables["/problem1"].sharedParameters + .allPossibleVariants, + ).eqls(["b", "e"]); + } + + // get same variants when add variantsToExclude + + core = await createTestCore({ + doenetML: createDoenetML({ exclude: ["a", "d", "h", "j"] }), + requestedVariantIndex: 1, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).eq(2); + expect(stateVariables["/_document1"].sharedParameters.variantSeed).eq( + variantsFromProblem ? "1" : "2", + ); + expect(stateVariables["/_document1"].sharedParameters.variantIndex).eq( + 1, + ); + expect(stateVariables["/_document1"].sharedParameters.variantName).eq( + documentAndProblemVariantsDiffer ? "a" : "b", + ); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls( + documentAndProblemVariantsDiffer + ? ["a", "b", "c", "d", "e", "f"] + : ["b", "c", "e", "f", "g", "i"], + ); + if (variantsFromProblem) { + expect(stateVariables["/problem1"].sharedParameters.variantSeed).eq( + "2", + ); + expect( + stateVariables["/problem1"].sharedParameters.variantIndex, + ).eq(1); + expect(stateVariables["/problem1"].sharedParameters.variantName).eq( + "b", + ); + expect( + stateVariables["/problem1"].sharedParameters + .allPossibleVariants, + ).eqls(["b", "c", "e", "f", "g", "i"]); + } + + core = await createTestCore({ + doenetML: createDoenetML({ exclude: ["a", "d", "h", "j"] }), + requestedVariantIndex: 3, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).eq(5); + + expect(stateVariables["/_document1"].sharedParameters.variantSeed).eq( + variantsFromProblem ? "3" : "5", + ); + expect(stateVariables["/_document1"].sharedParameters.variantIndex).eq( + 3, + ); + expect(stateVariables["/_document1"].sharedParameters.variantName).eq( + documentAndProblemVariantsDiffer ? "c" : "e", + ); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls( + documentAndProblemVariantsDiffer + ? ["a", "b", "c", "d", "e", "f"] + : ["b", "c", "e", "f", "g", "i"], + ); + if (variantsFromProblem) { + expect(stateVariables["/problem1"].sharedParameters.variantSeed).eq( + "5", + ); + expect( + stateVariables["/problem1"].sharedParameters.variantIndex, + ).eq(3); + expect(stateVariables["/problem1"].sharedParameters.variantName).eq( + "e", + ); + expect( + stateVariables["/problem1"].sharedParameters + .allPossibleVariants, + ).eqls(["b", "c", "e", "f", "g", "i"]); + } + + // get same variants when add variantsToInclude and variantsToExclude + + core = await createTestCore({ + doenetML: createDoenetML({ + include: ["a", "b", "d", "e", "g", "h"], + exclude: ["a", "c", "d", "h", "j"], + }), + requestedVariantIndex: 1, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).eq(2); + expect(stateVariables["/_document1"].sharedParameters.variantSeed).eq( + variantsFromProblem ? "1" : "2", + ); + expect(stateVariables["/_document1"].sharedParameters.variantIndex).eq( + 1, + ); + expect(stateVariables["/_document1"].sharedParameters.variantName).eq( + documentAndProblemVariantsDiffer ? "a" : "b", + ); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls( + documentAndProblemVariantsDiffer + ? ["a", "b", "c"] + : ["b", "e", "g"], + ); + if (variantsFromProblem) { + expect(stateVariables["/problem1"].sharedParameters.variantSeed).eq( + "2", + ); + expect( + stateVariables["/problem1"].sharedParameters.variantIndex, + ).eq(1); + expect(stateVariables["/problem1"].sharedParameters.variantName).eq( + "b", + ); + expect( + stateVariables["/problem1"].sharedParameters + .allPossibleVariants, + ).eqls(["b", "e", "g"]); + } + + core = await createTestCore({ + doenetML: createDoenetML({ + include: ["a", "b", "d", "e", "g", "h"], + exclude: ["a", "c", "d", "h", "j"], + }), + requestedVariantIndex: 2, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).eq(5); + expect(stateVariables["/_document1"].sharedParameters.variantSeed).eq( + variantsFromProblem ? "2" : "5", + ); + expect(stateVariables["/_document1"].sharedParameters.variantIndex).eq( + 2, + ); + expect(stateVariables["/_document1"].sharedParameters.variantName).eq( + documentAndProblemVariantsDiffer ? "b" : "e", + ); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls( + documentAndProblemVariantsDiffer + ? ["a", "b", "c"] + : ["b", "e", "g"], + ); + + if (variantsFromProblem) { + expect(stateVariables["/problem1"].sharedParameters.variantSeed).eq( + "5", + ); + expect( + stateVariables["/problem1"].sharedParameters.variantIndex, + ).eq(2); + expect(stateVariables["/problem1"].sharedParameters.variantName).eq( + "e", + ); + expect( + stateVariables["/problem1"].sharedParameters + .allPossibleVariants, + ).eqls(["b", "e", "g"]); + } + } + + it("variantsToInclude and variantsToExclude", async () => { + function createDoenetML({ + include = [], + exclude = [], + }: { include?: string[]; exclude?: string[] } = {}) { + let attributes = ""; + if (include.length > 0) { + attributes += `variantsToInclude="${include.join(" ")}"`; + } + if (exclude.length > 0) { + attributes += `variantsToExclude="${exclude.join(" ")}"`; + } + + return ` + + Selected number: + + `; + } + + await test_variants_include_exclude({ createDoenetML }); + }); + + it("variantsToInclude and variantsToExclude in problem as only child", async () => { + function createDoenetML({ + include = [], + exclude = [], + }: { include?: string[]; exclude?: string[] } = {}) { + let attributes = ""; + if (include.length > 0) { + attributes += `variantsToInclude="${include.join(" ")}"`; + } + if (exclude.length > 0) { + attributes += `variantsToExclude="${exclude.join(" ")}"`; + } + + return ` + + Hello! + + Selected number: + + + `; + } + + await test_variants_include_exclude({ + createDoenetML, + variantsFromProblem: true, + documentAndProblemVariantsDiffer: false, + }); + }); + + it("variantsToInclude and variantsToExclude in problem, extra child", async () => { + function createDoenetML({ + include = [], + exclude = [], + }: { include?: string[]; exclude?: string[] } = {}) { + let attributes = ""; + if (include.length > 0) { + attributes += `variantsToInclude="${include.join(" ")}"`; + } + if (exclude.length > 0) { + attributes += `variantsToExclude="${exclude.join(" ")}"`; + } + + return ` + Hello! + + + Selected number: + + + `; + } + + await test_variants_include_exclude({ + createDoenetML, + variantsFromProblem: true, + documentAndProblemVariantsDiffer: true, + }); + }); + + it("unique variants determined by numVariants specified, even with variantsToInclude and variantsToExclude", async () => { + // unique variants when numVariants is 1000 + + let doenetMLa = ` + + Selected number: + + `; + + let core = await createTestCore({ + doenetML: doenetMLa, + requestedVariantIndex: 1, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).eq(20); + expect(stateVariables["/_document1"].sharedParameters.variantSeed).eq( + "20", + ); + expect(stateVariables["/_document1"].sharedParameters.variantIndex).eq( + 1, + ); + expect(stateVariables["/_document1"].sharedParameters.variantName).eq( + "t", + ); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls(["t", "cv"]); + + core = await createTestCore({ + doenetML: doenetMLa, + requestedVariantIndex: 2, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).eq(100); + expect(stateVariables["/_document1"].sharedParameters.variantSeed).eq( + "100", + ); + expect(stateVariables["/_document1"].sharedParameters.variantIndex).eq( + 2, + ); + expect(stateVariables["/_document1"].sharedParameters.variantName).eq( + "cv", + ); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls(["t", "cv"]); + + // non-unique variants when numVariants is 100 + + let doenetMLb = ` + + Selected number: + + `; + + core = await createTestCore({ + doenetML: doenetMLb, + requestedVariantIndex: 1, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).not.eq(20); + expect(stateVariables["/_document1"].sharedParameters.variantSeed).eq( + "20", + ); + expect(stateVariables["/_document1"].sharedParameters.variantIndex).eq( + 1, + ); + expect(stateVariables["/_document1"].sharedParameters.variantName).eq( + "t", + ); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls(["t", "cv"]); + + core = await createTestCore({ + doenetML: doenetMLb, + requestedVariantIndex: 2, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).not.eq(100); + expect(stateVariables["/_document1"].sharedParameters.variantSeed).eq( + "100", + ); + expect(stateVariables["/_document1"].sharedParameters.variantIndex).eq( + 2, + ); + expect(stateVariables["/_document1"].sharedParameters.variantName).eq( + "cv", + ); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls(["t", "cv"]); + }); + + it("unless variant determines seed, sample random/prime numbers does not add variants", async () => { + // no other variants so get 1 variant + let core = await createTestCore({ + doenetML: ` + + `, + }); + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).gte(1).lte(10); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants, + ).eqls(["a"]); + + // just get 10 variants from select + core = await createTestCore({ + doenetML: ` + + + `, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).gte(1).lte(10000); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants + .length, + ).eq(10); + + // when variant determines seed, get 100 different variants + core = await createTestCore({ + doenetML: ` + + `, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).gte(1).lte(10); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants + .length, + ).eq(100); + + core = await createTestCore({ + doenetML: ` + + `, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n"].stateValues.value).gte(1).lte(10000); + expect( + stateVariables["/_document1"].sharedParameters.allPossibleVariants + .length, + ).eq(100); + }); +}); diff --git a/packages/test-cypress/cypress/e2e/variants/specifysinglevariant.cy.js b/packages/test-cypress/cypress/e2e/variants/specifysinglevariant.cy.js index 3db377047..0ad69ebfe 100644 --- a/packages/test-cypress/cypress/e2e/variants/specifysinglevariant.cy.js +++ b/packages/test-cypress/cypress/e2e/variants/specifysinglevariant.cy.js @@ -1,5 +1,4 @@ -import me from "math-expressions"; -import { cesc, cesc2, numberToLetters } from "@doenet/utils"; +import { cesc, cesc2 } from "@doenet/utils"; describe("Specifying single variant document tests", function () { beforeEach(() => { @@ -467,184 +466,6 @@ describe("Specifying single variant document tests", function () { } }); - it("excluded combinations of sequence items, reload", () => { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_allowLocalState").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - - cy.log("Test a bunch of variants"); - for (let ind = 1; ind <= 4; ind++) { - let doenetML = ` - ${ind} - - - - -

Enter $m: $m

-

Enter $x2: $x2

-

Enter $l1: $l1

- `; - - if (ind > 1) { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML, - requestedVariantIndex: ind, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - let indicesChosen1, indicesChosen2, indicesChosen3; - let m, n, x1, x2, l1, l2; - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - indicesChosen1 = [ - ...stateVariables["/_selectfromsequence1"].stateValues - .selectedIndices, - ]; - m = stateVariables["/m"].stateValues.value; - n = stateVariables["/n"].stateValues.value; - - indicesChosen2 = [ - ...stateVariables["/_selectfromsequence2"].stateValues - .selectedIndices, - ]; - x1 = stateVariables["/x1"].stateValues.value; - x2 = stateVariables["/x2"].stateValues.value; - - indicesChosen3 = [ - ...stateVariables["/_selectfromsequence3"].stateValues - .selectedIndices, - ]; - l1 = stateVariables["/l1"].stateValues.value; - l2 = stateVariables["/l2"].stateValues.value; - - cy.get(cesc("#\\/_mathinput1") + " textarea").type( - `${m}{enter}`, - { - force: true, - }, - ); - cy.get(cesc("#\\/_mathinput2") + " textarea").type( - `${me.fromAst(x2).toString()}{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/_textinput1_input")).type(`${l1}{enter}`); - cy.get(cesc("#\\/_mathinput1_correct")).should("be.visible"); - cy.get(cesc("#\\/_mathinput2_correct")).should("be.visible"); - cy.get(cesc("#\\/_textinput1_correct")).should("be.visible"); - - cy.wait(2000); // wait for 2 second debounce - cy.reload(); - - // don't need to give requested variant here, - // as will load variant from IndexedDB given the attempt number - cy.window().then(async (win) => { - win.postMessage( - { - doenetML, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - // wait until core is loaded - cy.waitUntil(() => - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - return stateVariables["/m"]; - }), - ); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_selectfromsequence1"].stateValues - .selectedIndices, - ).eqls(indicesChosen1); - expect(stateVariables["/m"].stateValues.value).eq(m); - expect(stateVariables["/n"].stateValues.value).eq(n); - expect( - stateVariables["/_selectfromsequence2"].stateValues - .selectedIndices, - ).eqls(indicesChosen2); - expect( - me - .fromAst(stateVariables["/x1"].stateValues.value) - .equals(me.fromAst(x1)), - ).be.true; - expect( - me - .fromAst(stateVariables["/x2"].stateValues.value) - .equals(me.fromAst(x2)), - ).be.true; - expect( - stateVariables["/_selectfromsequence1"].stateValues - .selectedIndices, - ).eqls(indicesChosen1); - expect(stateVariables["/l1"].stateValues.value).eq(l1); - expect(stateVariables["/l2"].stateValues.value).eq(l2); - }); - - cy.get(cesc("#\\/_mathinput1_correct")).should("be.visible"); - cy.get(cesc("#\\/_mathinput2_correct")).should("be.visible"); - cy.get(cesc("#\\/_textinput1_correct")).should("be.visible"); - - cy.get(cesc("#\\/_mathinput1") + " textarea").type(`{end}X`, { - force: true, - }); - cy.get(cesc("#\\/_mathinput2") + " textarea").type(`{end}X`, { - force: true, - }); - cy.get(cesc("#\\/_textinput1_input")).type(`{end}X`); - cy.get(cesc("#\\/_mathinput1_submit")).click(); - cy.get(cesc("#\\/_mathinput2_submit")).click(); - cy.get(cesc("#\\/_textinput1_submit")).click(); - cy.get(cesc("#\\/_mathinput1_incorrect")).should("be.visible"); - cy.get(cesc("#\\/_mathinput2_incorrect")).should("be.visible"); - cy.get(cesc("#\\/_textinput1_incorrect")).should("be.visible"); - - cy.get(cesc("#\\/_mathinput1") + " textarea").type( - `{end}{backspace}`, - { - force: true, - }, - ); - cy.get(cesc("#\\/_mathinput2") + " textarea").type( - `{end}{backspace}`, - { - force: true, - }, - ); - cy.get(cesc("#\\/_textinput1_input")).type(`{end}{backspace}`); - cy.get(cesc("#\\/_mathinput1_submit")).click(); - cy.get(cesc("#\\/_mathinput2_submit")).click(); - cy.get(cesc("#\\/_textinput1_submit")).click(); - cy.get(cesc("#\\/_mathinput1_correct")).should("be.visible"); - cy.get(cesc("#\\/_mathinput2_correct")).should("be.visible"); - cy.get(cesc("#\\/_textinput1_correct")).should("be.visible"); - }); - } - }); - it("replacements of composites are not included in generated variant info, reload", () => { cy.get("#testRunner_toggleControls").click(); cy.get("#testRunner_allowLocalState").click(); diff --git a/packages/test-cypress/cypress/e2e/variants/uniquevariants.cy.js b/packages/test-cypress/cypress/e2e/variants/uniquevariants.cy.js deleted file mode 100644 index b04217ddc..000000000 --- a/packages/test-cypress/cypress/e2e/variants/uniquevariants.cy.js +++ /dev/null @@ -1,5295 +0,0 @@ -import { cesc, cesc2 } from "@doenet/utils"; - -describe("Specifying unique variant tests", function () { - beforeEach(() => { - cy.clearIndexedDB(); - cy.visit("/"); - }); - - it("single select", () => { - let values = ["u", "v", "w", "x", "y", "z"]; - - cy.log("get all values in order and they repeat in next variants"); - for (let ind = 1; ind <= 18; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.get(cesc("#\\/x") + " .mjx-mrow").should( - "have.text", - values[(ind - 1) % 6], - ); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/x"].stateValues.value).eq( - values[(ind - 1) % 6], - ); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f"]); - }); - } - }); - - it("single selectfromsequence", () => { - cy.log("get all values in order and they repeat in next variants"); - for (let ind = 1; ind <= 15; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.get(cesc("#\\/x")).should("have.text", ((ind - 1) % 5) + 1); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/x"].stateValues.value).eq( - ((ind - 1) % 5) + 1, - ); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e"]); - }); - } - }); - - it("selectfromsequence with excludes", () => { - cy.log("get all values in order and they repeat in next variants"); - for (let ind = 1; ind <= 12; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - let letters = ["c", "e", "i", "m"]; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.get(cesc("#\\/x")).should("have.text", letters[(ind - 1) % 4]); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/x"].stateValues.value).eq( - letters[(ind - 1) % 4], - ); - }); - } - }); - - it("select and selectfromsequence combination", () => { - let valuesW = ["m", "n"]; - let valuesX = ["x", "y", "z"]; - let valuesY = [2, 3, 4]; - let valuesZ = [3, 7]; - - let values = []; - for (let w of valuesW) { - for (let x of valuesX) { - for (let y of valuesY) { - for (let z of valuesZ) { - values.push([w, x, y, z].join(",")); - } - } - } - } - let valuesFound = []; - - let numVariants = - valuesW.length * valuesX.length * valuesY.length * valuesZ.length; - - let wsFound = [], - xsFound = [], - ysFound = [], - zsFound = []; - - cy.log("get all values in variants"); - for (let ind = 1; ind <= numVariants; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newW = stateVariables["/w"].stateValues.value; - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newZ = stateVariables["/z"].stateValues.value; - let newValue = [newW, newX, newY, newZ].join(","); - expect(values.includes(newValue)).eq(true); - expect(valuesFound.includes(newValue)).eq(false); - valuesFound.push(newValue); - - if (ind <= 3) { - wsFound.push(newW); - xsFound.push(newX); - ysFound.push(newY); - zsFound.push(newZ); - } - }); - } - - cy.log("all individual options selected in first variants"); - cy.window().then(async (win) => { - expect(wsFound.slice(0, 2).sort()).eqls(valuesW); - expect(xsFound.sort()).eqls(valuesX); - expect(ysFound.sort()).eqls(valuesY); - expect(zsFound.slice(0, 2).sort()).eqls(valuesZ); - }); - - cy.log("values begin to repeat in next variants"); - cy.reload(); - for (let ind = numVariants + 1; ind <= numVariants + 15; ind += 3) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newW = stateVariables["/w"].stateValues.value; - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newZ = stateVariables["/z"].stateValues.value; - let newValue = [newW, newX, newY, newZ].join(","); - - expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); - }); - } - }); - - it("select multiple", () => { - let valuesSingle = ["w", "x", "y", "z"]; - let valuesFound = []; - let values = []; - for (let x of valuesSingle) { - for (let y of valuesSingle) { - if (y == x) { - continue; - } - for (let z of valuesSingle) { - if (z === x || z === y) { - continue; - } - values.push([x, y, z].join(",")); - } - } - } - - let numVariants = values.length; - - let xsFound = [], - ysFound = [], - zsFound = []; - - cy.log("get all values in first variants"); - for (let ind = 1; ind <= numVariants; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newZ = stateVariables["/z"].stateValues.value; - let newValue = [newX, newY, newZ].join(","); - expect(values.includes(newValue)).eq(true); - expect(valuesFound.includes(newValue)).eq(false); - valuesFound.push(newValue); - - if (ind <= 4) { - xsFound.push(newX); - ysFound.push(newY); - zsFound.push(newZ); - } - }); - } - - cy.log("all individual options selected in first variants"); - cy.window().then(async (win) => { - expect(xsFound.sort()).eqls(valuesSingle); - expect(ysFound.sort()).eqls(valuesSingle); - expect(zsFound.sort()).eqls(valuesSingle); - }); - - cy.log("values begin to repeat in next variants"); - cy.reload(); - for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newZ = stateVariables["/z"].stateValues.value; - let newValue = [newX, newY, newZ].join(","); - - expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); - }); - } - }); - - it("select multiple with replacement", () => { - let valuesSingle = ["x", "y", "z"]; - let valuesFound = []; - let values = []; - for (let x of valuesSingle) { - for (let y of valuesSingle) { - for (let z of valuesSingle) { - values.push([x, y, z].join(",")); - } - } - } - - let numVariants = values.length; - let xsFound = [], - ysFound = [], - zsFound = []; - - cy.log("get all values in first variants"); - for (let ind = 1; ind <= numVariants; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newZ = stateVariables["/z"].stateValues.value; - let newValue = [newX, newY, newZ].join(","); - expect(values.includes(newValue)).eq(true); - expect(valuesFound.includes(newValue)).eq(false); - valuesFound.push(newValue); - - if (ind <= 3) { - xsFound.push(newX); - ysFound.push(newY); - zsFound.push(newZ); - } - }); - } - - cy.log("all individual options selected in first variants"); - cy.window().then(async (win) => { - expect(xsFound.sort()).eqls(valuesSingle); - expect(ysFound.sort()).eqls(valuesSingle); - expect(zsFound.sort()).eqls(valuesSingle); - }); - - cy.log("values begin to repeat in next variants"); - cy.reload(); - for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newZ = stateVariables["/z"].stateValues.value; - let newValue = [newX, newY, newZ].join(","); - - expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); - }); - } - }); - - it("select multiple from sequence", () => { - let valuesSingle = ["w", "x", "y", "z"]; - let valuesFound = []; - let values = []; - for (let x of valuesSingle) { - for (let y of valuesSingle) { - if (y == x) { - continue; - } - for (let z of valuesSingle) { - if (z === x || z === y) { - continue; - } - values.push([x, y, z].join(",")); - } - } - } - - let numVariants = values.length; - let xsFound = [], - ysFound = [], - zsFound = []; - - cy.log("get all values in first variants"); - for (let ind = 1; ind <= numVariants; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newZ = stateVariables["/z"].stateValues.value; - let newValue = [newX, newY, newZ].join(","); - expect(values.includes(newValue)).eq(true); - expect(valuesFound.includes(newValue)).eq(false); - valuesFound.push(newValue); - - if (ind <= 4) { - xsFound.push(newX); - ysFound.push(newY); - zsFound.push(newZ); - } - }); - } - - cy.log("all individual options selected in first variants"); - cy.window().then(async (win) => { - expect(xsFound.sort()).eqls(valuesSingle); - expect(ysFound.sort()).eqls(valuesSingle); - expect(zsFound.sort()).eqls(valuesSingle); - }); - - cy.log("values begin to repeat in next variants"); - cy.reload(); - for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newZ = stateVariables["/z"].stateValues.value; - let newValue = [newX, newY, newZ].join(","); - - expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); - }); - } - }); - - it("select multiple from sequence with replacement", () => { - let valuesSingle = ["x", "y", "z"]; - let valuesFound = []; - let values = []; - for (let x of valuesSingle) { - for (let y of valuesSingle) { - for (let z of valuesSingle) { - values.push([x, y, z].join(",")); - } - } - } - - let numVariants = values.length; - let xsFound = [], - ysFound = [], - zsFound = []; - - cy.log("get all values in first variants"); - for (let ind = 1; ind <= numVariants; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newZ = stateVariables["/z"].stateValues.value; - let newValue = [newX, newY, newZ].join(","); - expect(values.includes(newValue)).eq(true); - expect(valuesFound.includes(newValue)).eq(false); - valuesFound.push(newValue); - - if (ind <= 3) { - xsFound.push(newX); - ysFound.push(newY); - zsFound.push(newZ); - } - }); - } - - cy.log("all individual options selected in first variants"); - cy.window().then(async (win) => { - expect(xsFound.sort()).eqls(valuesSingle); - expect(ysFound.sort()).eqls(valuesSingle); - expect(zsFound.sort()).eqls(valuesSingle); - }); - - cy.log("values begin to repeat in next variants"); - cy.reload(); - for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newZ = stateVariables["/z"].stateValues.value; - let newValue = [newX, newY, newZ].join(","); - - expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); - }); - } - }); - - it("limit variants", () => { - let valuesSingle = ["u", "v", "w", "x", "y", "z"]; - let valuesFound = []; - let values = []; - for (let w of valuesSingle) { - for (let x of valuesSingle) { - for (let y of valuesSingle) { - for (let z of valuesSingle) { - values.push([w, x, y, z].join(",")); - } - } - } - } - - let numVariants = 10; - let wsFound = [], - xsFound = [], - ysFound = [], - zsFound = []; - - cy.log("get unique values in first variants"); - for (let ind = 1; ind <= numVariants; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newW = stateVariables["/w"].stateValues.value; - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newZ = stateVariables["/z"].stateValues.value; - let newValue = [newW, newX, newY, newZ].join(","); - expect(values.includes(newValue)).eq(true); - expect(valuesFound.includes(newValue)).eq(false); - valuesFound.push(newValue); - - if (ind <= 6) { - wsFound.push(newW); - xsFound.push(newX); - ysFound.push(newY); - zsFound.push(newZ); - } - }); - } - - cy.log("all individual options selected in first variants"); - cy.window().then(async (win) => { - expect(wsFound.sort()).eqls(valuesSingle); - expect(xsFound.sort()).eqls(valuesSingle); - expect(ysFound.sort()).eqls(valuesSingle); - expect(zsFound.sort()).eqls(valuesSingle); - }); - - cy.log("values repeat in next variants"); - cy.reload(); - for (let ind = numVariants + 1; ind <= 2 * numVariants + 3; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newW = stateVariables["/w"].stateValues.value; - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newZ = stateVariables["/z"].stateValues.value; - let newValue = [newW, newX, newY, newZ].join(","); - - expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); - }); - } - }); - - it("selects of selectfromsequence", () => { - let valuesFound = []; - let values = [1, 2, 101, 102, 103, 201, 202, 203, 204]; - let numVariants = values.length; - - cy.log("get all values in first variants"); - for (let ind = 1; ind <= numVariants; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newValue = stateVariables["/x"].stateValues.value; - expect(values.includes(newValue)).eq(true); - expect(valuesFound.includes(newValue)).eq(false); - valuesFound.push(newValue); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f", "g", "h", "i"]); - - if (ind === 3) { - cy.log("all individual groups selected in first variants"); - cy.window().then(async (win) => { - expect(valuesFound.some((x) => x <= 2)).eq(true); - expect( - valuesFound.some((x) => x >= 101 && x <= 103), - ).eq(true); - expect( - valuesFound.some((x) => x >= 201 && x <= 204), - ).eq(true); - }); - } - - if (ind === 6) { - cy.log( - "all individual groups selected twice in first variants", - ); - cy.window().then(async (win) => { - expect( - valuesFound.reduce( - (a, c) => a + (c <= 2 ? 1 : 0), - 0, - ), - ).eq(2); - expect( - valuesFound.reduce( - (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), - 0, - ), - ).eq(2); - expect( - valuesFound.reduce( - (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), - 0, - ), - ).eq(2); - }); - } - - if (ind === 8) { - cy.log( - "most individual groups selected three times in first variants", - ); - cy.window().then(async (win) => { - expect( - valuesFound.reduce( - (a, c) => a + (c <= 2 ? 1 : 0), - 0, - ), - ).eq(2); - expect( - valuesFound.reduce( - (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), - 0, - ), - ).eq(3); - expect( - valuesFound.reduce( - (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), - 0, - ), - ).eq(3); - }); - } - }); - } - - cy.log("values repeat in next variants"); - cy.reload(); - for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newValue = stateVariables["/x"].stateValues.value; - expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); - }); - } - }); - - it("selects of selects", () => { - let valuesFound = []; - let values = [1, 2, 101, 102, 103, 201, 202, 203, 204]; - let numVariants = values.length; - - cy.log("get all values in first variants"); - for (let ind = 1; ind <= numVariants; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - 1 2 - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newValue = stateVariables["/x"].stateValues.value; - expect(values.includes(newValue)).eq(true); - expect(valuesFound.includes(newValue)).eq(false); - valuesFound.push(newValue); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f", "g", "h", "i"]); - - if (ind === 3) { - cy.log("all individual groups selected in first variants"); - cy.window().then(async (win) => { - expect(valuesFound.some((x) => x <= 2)).eq(true); - expect( - valuesFound.some((x) => x >= 101 && x <= 103), - ).eq(true); - expect( - valuesFound.some((x) => x >= 201 && x <= 204), - ).eq(true); - }); - } - - if (ind === 6) { - cy.log( - "all individual groups selected twice in first variants", - ); - cy.window().then(async (win) => { - expect( - valuesFound.reduce( - (a, c) => a + (c <= 2 ? 1 : 0), - 0, - ), - ).eq(2); - expect( - valuesFound.reduce( - (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), - 0, - ), - ).eq(2); - expect( - valuesFound.reduce( - (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), - 0, - ), - ).eq(2); - }); - } - - if (ind === 8) { - cy.log( - "most individual groups selected three times in first variants", - ); - cy.window().then(async (win) => { - expect( - valuesFound.reduce( - (a, c) => a + (c <= 2 ? 1 : 0), - 0, - ), - ).eq(2); - expect( - valuesFound.reduce( - (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), - 0, - ), - ).eq(3); - expect( - valuesFound.reduce( - (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), - 0, - ), - ).eq(3); - }); - } - }); - } - - cy.log("values repeat in next variants"); - cy.reload(); - for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - 1 2 - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newValue = stateVariables["/x"].stateValues.value; - expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); - }); - } - }); - - it("selects of paragraphs of selects/selectfromsequence", () => { - let valuesFound = []; - let values = [1, 2, 101, 102, 103, 201, 202, 203, 204]; - let numVariants = values.length; - - cy.log("get all values in first variants"); - for (let ind = 1; ind <= numVariants; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - 1 2

- - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newValue = stateVariables["/x/n"].stateValues.value; - expect(values.includes(newValue)).eq(true); - expect(valuesFound.includes(newValue)).eq(false); - valuesFound.push(newValue); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f", "g", "h", "i"]); - - if (ind === 3) { - cy.log("all individual groups selected in first variants"); - cy.window().then(async (win) => { - expect(valuesFound.some((x) => x <= 2)).eq(true); - expect( - valuesFound.some((x) => x >= 101 && x <= 103), - ).eq(true); - expect( - valuesFound.some((x) => x >= 201 && x <= 204), - ).eq(true); - }); - } - - if (ind === 6) { - cy.log( - "all individual groups selected twice in first variants", - ); - cy.window().then(async (win) => { - expect( - valuesFound.reduce( - (a, c) => a + (c <= 2 ? 1 : 0), - 0, - ), - ).eq(2); - expect( - valuesFound.reduce( - (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), - 0, - ), - ).eq(2); - expect( - valuesFound.reduce( - (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), - 0, - ), - ).eq(2); - }); - } - - if (ind === 8) { - cy.log( - "most individual groups selected three times in first variants", - ); - cy.window().then(async (win) => { - expect( - valuesFound.reduce( - (a, c) => a + (c <= 2 ? 1 : 0), - 0, - ), - ).eq(2); - expect( - valuesFound.reduce( - (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), - 0, - ), - ).eq(3); - expect( - valuesFound.reduce( - (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), - 0, - ), - ).eq(3); - }); - } - }); - } - - cy.log("values repeat in next variants"); - cy.reload(); - for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - 1 2

- - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newValue = stateVariables["/x/n"].stateValues.value; - expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); - }); - } - }); - - it("selects of selects, select multiple", () => { - let valuesFound = []; - let valuesSingle = [1, 2, 101, 102, 103, 201, 202, 203, 204]; - let values = []; - for (let x of valuesSingle) { - for (let y of valuesSingle) { - if (Math.abs(y - x) > 5) { - values.push([x, y].join(",")); - } - } - } - let numVariants = values.length; - - cy.log("get unique values in first variants"); - for (let ind = 1; ind <= 20; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - 1 2 - - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newValue = [newX, newY].join(","); - expect(values.includes(newValue)).eq(true); - expect(valuesFound.includes(newValue)).eq(false); - valuesFound.push(newValue); - }); - } - - cy.log("values repeat in next variants"); - cy.reload(); - for (let ind = numVariants + 1; ind <= numVariants + 20; ind += 5) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - 1 2 - - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let newX = stateVariables["/x"].stateValues.value; - let newY = stateVariables["/y"].stateValues.value; - let newValue = [newX, newY].join(","); - expect(newValue).eq(valuesFound[(ind - 1) % numVariants]); - }); - } - - cy.log("selects all individual groups equally in first variants"); - let valuesFound1 = []; - let valuesFound2 = []; - for (let pass = 0; pass < 12; pass++) { - for (let ind = pass * 3 + 1; ind <= (pass + 1) * 3; ind++) { - // reload every 10 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 10 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - 1 2 - - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - valuesFound1.push(stateVariables["/x"].stateValues.value); - valuesFound2.push(stateVariables["/y"].stateValues.value); - }); - } - cy.window().then(async (win) => { - expect( - valuesFound1.reduce((a, c) => a + (c <= 2 ? 1 : 0), 0), - ).eq(pass + 1); - expect( - valuesFound1.reduce( - (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), - 0, - ), - ).eq(pass + 1); - expect( - valuesFound1.reduce( - (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), - 0, - ), - ).eq(pass + 1); - expect( - valuesFound2.reduce((a, c) => a + (c <= 2 ? 1 : 0), 0), - ).eq(pass + 1); - expect( - valuesFound2.reduce( - (a, c) => a + (c >= 101 && c <= 103 ? 1 : 0), - 0, - ), - ).eq(pass + 1); - expect( - valuesFound2.reduce( - (a, c) => a + (c >= 201 && c <= 204 ? 1 : 0), - 0, - ), - ).eq(pass + 1); - }); - } - }); - - it("deeper nesting of selects/selectfromsequence", () => { - let doenetML = ` - - - - - - -

- - - - - - `; - - let valuesFound = []; - - let colorsA = [ - "red", - "orange", - "yellow", - "magenta", - "maroon", - "fuchsia", - "scarlet", - ]; - let colorsB = ["green", "chartreuse", "turquoise"]; - let colorsC = ["white", "black"]; - let allColors = [...colorsA, ...colorsB, ...colorsC]; - - let letters = [...Array(26)].map((_, i) => - String.fromCharCode("a".charCodeAt(0) + i), - ); - - let variables = ["u", "v", "w", "x", "y", "z"]; - - let categories = [ - "Favorite color:", - "Selected number:", - "Chosen letter:", - "Variable:", - ]; - - let numVariants = 24; - - let colorsFound = []; - let numbersFound = []; - let lettersFound = []; - let variablesFound = []; - let categoriesFound = []; - - cy.log("get all values in first variants"); - for (let ind = 1; ind <= numVariants; ind++) { - // reload every 8 times to keep it from slowing down - // (presumably due to garbage collecting) - if (ind % 8 === 0) { - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let category = stateVariables["/p"].activeChildren[0].trim(); - expect(categories.includes(category)).eq(true); - - let component = - stateVariables[ - stateVariables["/p"].activeChildren.filter( - (x) => x.componentName, - )[0].componentName - ]; - let newValue = component.stateValues.value; - if (category === categories[0]) { - expect(allColors.includes(newValue)).eq(true); - colorsFound.push(newValue); - } else if (category === categories[1]) { - let validNum = - Number.isInteger(newValue) && - ((newValue >= 1000 && newValue <= 2000) || - (newValue >= -1000 && newValue <= -900)); - expect(validNum).eq(true); - numbersFound.push(newValue); - } else if (category === categories[2]) { - expect(letters.includes(newValue)).eq(true); - lettersFound.push(newValue); - } else { - expect(variables.includes(newValue)).eq(true); - variablesFound.push(newValue); - } - - let combinedValue = [category, newValue].join(","); - - expect(valuesFound.includes(combinedValue)).eq(false); - valuesFound.push(combinedValue); - - categoriesFound.push(category); - - if (ind === 4) { - cy.log("all individual groups selected in first variants"); - cy.window().then(async (win) => { - for (let ind = 0; ind < 4; ind++) { - expect( - categoriesFound.includes(categories[ind]), - ).eq(true); - } - }); - } - - if (ind === 8) { - cy.log( - "all individual groups selected twice in first variants", - ); - cy.window().then(async (win) => { - for (let ind = 0; ind < 4; ind++) { - expect( - categoriesFound - .slice(4, 8) - .includes(categories[ind]), - ).eq(true); - } - }); - } - }); - } - - cy.log( - "the 24 values are distributed 6 to each category and evenly distributed across subcategories", - ); - cy.window().then(async (win) => { - let colorsFoundSet = new Set(colorsFound); - expect(colorsFoundSet.size).eq(6); - expect( - colorsA.reduce( - (a, c) => a + (colorsFoundSet.has(c) ? 1 : 0), - 0, - ), - ).eq(2); - expect( - colorsB.reduce( - (a, c) => a + (colorsFoundSet.has(c) ? 1 : 0), - 0, - ), - ).eq(2); - expect( - colorsC.reduce( - (a, c) => a + (colorsFoundSet.has(c) ? 1 : 0), - 0, - ), - ).eq(2); - - expect(numbersFound.reduce((a, c) => a + (c > 0 ? 1 : 0), 0)).eq(3); - expect(numbersFound.reduce((a, c) => a + (c < 0 ? 1 : 0), 0)).eq(3); - - expect(lettersFound.length).eq(6); - expect(variablesFound.length).eq(6); - - expect(variablesFound.sort()).eqls(variables); - }); - - cy.log("values repeat in next variants"); - cy.reload(); - for (let ind = numVariants + 1; ind <= numVariants + 25; ind += 5) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let category = stateVariables["/p"].activeChildren[0].trim(); - let component = - stateVariables[ - stateVariables["/p"].activeChildren.filter( - (x) => x.componentName, - )[0].componentName - ]; - let newValue = component.stateValues.value; - let combinedValue = [category, newValue].join(","); - expect(combinedValue).eq(valuesFound[(ind - 1) % numVariants]); - }); - } - }); - - it("select problems of selects/selectfromsequence", () => { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_allowLocalState").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - - let doenetML = ` - - - - - -

Enter the color $(p/color): $(p/color)

- - - - - -

Enter the word $(p/word): $(p/word)

- - - - - `; - - let valuesFound = []; - - let colorsA = [ - "red", - "orange", - "yellow", - "magenta", - "maroon", - "fuchsia", - "scarlet", - ]; - let colorsB = ["green", "chartreuse", "turquoise"]; - let allColors = [...colorsA, ...colorsB]; - - let wordsA = ["run", "walk", "jump", "skip"]; - let wordsB = [ - "soft", - "scary", - "large", - "empty", - "residual", - "limitless", - ]; - let allWords = [...wordsA, ...wordsB]; - - let letters = [...Array(26)].map((_, i) => - String.fromCharCode("a".charCodeAt(0) + i), - ); - - let categories = ["Favorite color", "Selected word", "Chosen letter"]; - - let numVariants = 6; - - let categoriesFound = []; - let colorsFound = []; - let wordsFound = []; - let lettersFound = []; - - cy.log("get all values in first variants"); - for (let ind = 1; ind <= numVariants; ind++) { - if (ind > 1) { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - let category, newValue; - - let textinputName; - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - textinputName = - stateVariables[`/problem/ans`].stateValues.inputChildren[0] - .componentName; - category = stateVariables["/problem"].stateValues.title; - expect(categories.includes(category)).eq(true); - - let component = - stateVariables[ - stateVariables[ - stateVariables["/problem"].activeChildren.filter( - (x) => x.componentName, - )[1].componentName - ].activeChildren[1].componentName - ]; - newValue = component.stateValues.value; - if (category === categories[0]) { - expect(allColors.includes(newValue)).eq(true); - colorsFound.push(newValue); - } else if (category === categories[1]) { - expect(allWords.includes(newValue)).eq(true); - wordsFound.push(newValue); - } else if (category === categories[2]) { - expect(letters.includes(newValue)).eq(true); - lettersFound.push(newValue); - } - - let combinedValue = [category, newValue].join(","); - - expect(valuesFound.includes(combinedValue)).eq(false); - valuesFound.push(combinedValue); - - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f"]); - - categoriesFound.push(category); - - if (ind === 3) { - cy.log("all individual groups selected in first variants"); - cy.window().then(async (win) => { - for (let ind = 0; ind < 3; ind++) { - expect( - categoriesFound.includes(categories[ind]), - ).eq(true); - } - }); - } - - if (ind === 6) { - cy.log( - "all individual groups selected twice in first variants", - ); - cy.window().then(async (win) => { - for (let ind = 0; ind < 3; ind++) { - expect( - categoriesFound - .slice(3) - .includes(categories[ind]), - ).eq(true); - } - }); - } - }); - - cy.window().then(async (win) => { - let textinputAnchor = cesc2("#" + textinputName) + "_input"; - let answerCorrect = cesc2("#" + textinputName + "_correct"); - let answerIncorrect = cesc2("#" + textinputName + "_incorrect"); - let answerSubmit = cesc2("#" + textinputName + "_submit"); - - cy.get(textinputAnchor).type(`${newValue}{enter}`); - - cy.get(answerCorrect).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/problem/ans"].stateValues - .creditAchieved, - ).eq(1); - expect( - stateVariables["/problem/ans"].stateValues - .submittedResponses, - ).eqls([newValue]); - expect(stateVariables[textinputName].stateValues.value).eq( - newValue, - ); - }); - - cy.wait(1500); // wait for 1 second debounce - - cy.reload(); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - // wait until core is loaded - cy.waitUntil(() => - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - return stateVariables["/problem/ans"]; - }), - ); - - cy.get(answerCorrect).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/problem/ans"].stateValues - .creditAchieved, - ).eq(1); - expect( - stateVariables["/problem/ans"].stateValues - .submittedResponses, - ).eqls([newValue]); - expect(stateVariables[textinputName].stateValues.value).eq( - newValue, - ); - }); - - cy.get(textinputAnchor).type(`{end}X`); - cy.get(answerSubmit).click(); - cy.get(answerIncorrect).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/problem/ans"].stateValues - .creditAchieved, - ).eq(0); - expect( - stateVariables["/problem/ans"].stateValues - .submittedResponses, - ).eqls([newValue + "X"]); - expect(stateVariables[textinputName].stateValues.value).eq( - newValue + "X", - ); - }); - - cy.get(textinputAnchor).type(`{end}{backspace}`); - cy.get(answerSubmit).click(); - cy.get(answerCorrect).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/problem/ans"].stateValues - .creditAchieved, - ).eq(1); - expect( - stateVariables["/problem/ans"].stateValues - .submittedResponses, - ).eqls([newValue]); - expect(stateVariables[textinputName].stateValues.value).eq( - newValue, - ); - }); - }); - } - - cy.window().then(async (win) => { - let colorsFoundSet = new Set(colorsFound); - expect(colorsFoundSet.size).eq(2); - expect( - colorsA.reduce( - (a, c) => a + (colorsFoundSet.has(c) ? 1 : 0), - 0, - ), - ).eq(1); - expect( - colorsB.reduce( - (a, c) => a + (colorsFoundSet.has(c) ? 1 : 0), - 0, - ), - ).eq(1); - - let wordsFoundSet = new Set(wordsFound); - expect(wordsFoundSet.size).eq(2); - expect( - wordsA.reduce((a, c) => a + (wordsFoundSet.has(c) ? 1 : 0), 0), - ).eq(1); - expect( - wordsB.reduce((a, c) => a + (wordsFoundSet.has(c) ? 1 : 0), 0), - ).eq(1); - }); - - cy.log("values repeat in next variants"); - for (let ind = numVariants + 1; ind <= numVariants + 6; ind += 2) { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let category = stateVariables["/problem"].stateValues.title; - let component = - stateVariables[ - stateVariables[ - stateVariables["/problem"].activeChildren.filter( - (x) => x.componentName, - )[1].componentName - ].activeChildren[1].componentName - ]; - let newValue = component.stateValues.value; - let combinedValue = [category, newValue].join(","); - expect(combinedValue).eq(valuesFound[(ind - 1) % numVariants]); - }); - } - }); - - it("can get unique with map without variants", () => { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_allowLocalState").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - - let doenetML = ` - - - - - - - - -

N:

- `; - - cy.log("get all values in order and they repeat in next variants"); - for (let ind = 1; ind <= 4; ind++) { - if (ind > 1) { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.get(cesc("#\\/x")).should("have.text", ((ind - 1) % 3) + 1); - - cy.get(cesc("#\\/p1")).should("have.text", "letter: a"); - cy.get(cesc("#\\/p2")).should("not.exist"); - - cy.get(cesc("#\\/n") + " textarea").type( - "{end}{backspace}3{enter}", - { - force: true, - }, - ); - cy.get(cesc("#\\/p1")).should("have.text", "letter: a"); - cy.get(cesc("#\\/p2")).should("have.text", "letter: b"); - cy.get(cesc("#\\/p3")).should("have.text", "letter: c"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/x"].stateValues.value).eq( - ((ind - 1) % 3) + 1, - ); - expect( - stateVariables[ - stateVariables["/p1"].activeChildren[1].componentName - ].stateValues.value, - ).eq("a"); - expect( - stateVariables[ - stateVariables["/p2"].activeChildren[1].componentName - ].stateValues.value, - ).eq("b"); - expect( - stateVariables[ - stateVariables["/p3"].activeChildren[1].componentName - ].stateValues.value, - ).eq("c"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c"]); - }); - - cy.wait(1500); // wait for 1 second debounce - cy.reload(); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - // wait until core is loaded - cy.waitUntil(() => - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - return stateVariables["/x"]; - }), - ); - - cy.get(cesc("#\\/x")).should("have.text", ((ind - 1) % 3) + 1); - - cy.get(cesc("#\\/p1")).should("have.text", "letter: a"); - cy.get(cesc("#\\/p2")).should("have.text", "letter: b"); - cy.get(cesc("#\\/p3")).should("have.text", "letter: c"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/x"].stateValues.value).eq( - ((ind - 1) % 3) + 1, - ); - expect( - stateVariables[ - stateVariables["/p1"].activeChildren[1].componentName - ].stateValues.value, - ).eq("a"); - expect( - stateVariables[ - stateVariables["/p2"].activeChildren[1].componentName - ].stateValues.value, - ).eq("b"); - expect( - stateVariables[ - stateVariables["/p3"].activeChildren[1].componentName - ].stateValues.value, - ).eq("c"); - }); - - cy.get(cesc("#\\/n") + " textarea").type( - "{end}{backspace}4{enter}", - { - force: true, - }, - ); - cy.get(cesc("#\\/p1")).should("have.text", "letter: a"); - cy.get(cesc("#\\/p2")).should("have.text", "letter: b"); - cy.get(cesc("#\\/p3")).should("have.text", "letter: c"); - cy.get(cesc("#\\/p4")).should("have.text", "letter: d"); - } - }); - - it("single shuffled choiceinput", () => { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_allowLocalState").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - - let doenetML = ` - - - red - blue - green - -

Selected value:

- - `; - - let ordersFound = []; - let choices = ["red", "blue", "green"]; - - cy.log("get all orders in first 6 variants"); - for (let ind = 1; ind <= 6; ind++) { - if (ind > 1) { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let choiceOrder = stateVariables["/ci"].stateValues.choiceOrder; - let selectedOrder = choiceOrder.join(","); - expect(ordersFound.includes(selectedOrder)).eq(false); - ordersFound.push(selectedOrder); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f"]); - - for (let i = 0; i < 3; i++) { - cy.get(cesc(`#\\/ci_choice${i + 1}_input`)).click(); - cy.get(cesc("#\\/selectedValue")).should( - "have.text", - choices[choiceOrder[i] - 1], - ); - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - expect( - stateVariables["/ci"].stateValues.selectedValues, - ).eqls([choices[choiceOrder[i] - 1]]); - }); - } - - cy.wait(1500); // wait for 1 second debounce - cy.reload(); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - // wait until core is loaded - cy.waitUntil(() => - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - return stateVariables["/ci"]; - }), - ); - - cy.get(cesc("#\\/selectedValue")).should( - "have.text", - choices[choiceOrder[2] - 1], - ); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/ci"].stateValues.selectedValues, - ).eqls([choices[choiceOrder[2] - 1]]); - }); - - cy.get(cesc(`#\\/ci_choice1_input`)).click(); - cy.get(cesc("#\\/selectedValue")).should( - "have.text", - choices[choiceOrder[0] - 1], - ); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/ci"].stateValues.selectedValues, - ).eqls([choices[choiceOrder[0] - 1]]); - }); - }); - } - - cy.log("7th variant repeats first order"); - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - - let ind = 7; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let choiceOrder = stateVariables["/ci"].stateValues.choiceOrder; - let selectedOrder = choiceOrder.join(","); - expect(selectedOrder).eq(ordersFound[0]); - }); - }); - - it("single shuffled choiceinput, choices copied in", () => { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_allowLocalState").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - - let doenetML = ` - - red - - blue - green - - - - - - -

Selected value:

- - `; - - let ordersFound = []; - let choices = ["red", "blue", "green"]; - - cy.log("get all orders in first 6 variants"); - for (let ind = 1; ind <= 6; ind++) { - if (ind > 1) { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let choiceOrder = stateVariables["/ci"].stateValues.choiceOrder; - let selectedOrder = choiceOrder.join(","); - expect(ordersFound.includes(selectedOrder)).eq(false); - ordersFound.push(selectedOrder); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f"]); - - for (let i = 0; i < 3; i++) { - cy.get(cesc(`#\\/ci_choice${i + 1}_input`)).click(); - cy.get(cesc("#\\/selectedValue")).should( - "have.text", - choices[choiceOrder[i] - 1], - ); - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - expect( - stateVariables["/ci"].stateValues.selectedValues, - ).eqls([choices[choiceOrder[i] - 1]]); - }); - } - - cy.wait(1500); // wait for 1 second debounce - cy.reload(); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - // wait until core is loaded - cy.waitUntil(() => - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - return stateVariables["/ci"]; - }), - ); - - cy.get(cesc("#\\/selectedValue")).should( - "have.text", - choices[choiceOrder[2] - 1], - ); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/ci"].stateValues.selectedValues, - ).eqls([choices[choiceOrder[2] - 1]]); - }); - - cy.get(cesc(`#\\/ci_choice1_input`)).click(); - cy.get(cesc("#\\/selectedValue")).should( - "have.text", - choices[choiceOrder[0] - 1], - ); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/ci"].stateValues.selectedValues, - ).eqls([choices[choiceOrder[0] - 1]]); - }); - }); - } - - cy.log("7th variant repeats first order"); - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - - let ind = 7; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let choiceOrder = stateVariables["/ci"].stateValues.choiceOrder; - let selectedOrder = choiceOrder.join(","); - expect(selectedOrder).eq(ordersFound[0]); - }); - }); - - it("single shuffled choiceinput sugared inside answer", () => { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_allowLocalState").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - - let doenetML = ` - - red - blue - green - -

Submitted response:

- - `; - - let ordersFound = []; - let choices = ["red", "blue", "green"]; - - cy.log("get all orders in first 6 variants"); - for (let ind = 1; ind <= 6; ind++) { - if (ind > 1) { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let choiceInputName = - stateVariables["/ans"].stateValues.inputChildren[0] - .componentName; - let choiceOrder = - stateVariables[choiceInputName].stateValues.choiceOrder; - let selectedOrder = choiceOrder.join(","); - expect(ordersFound.includes(selectedOrder)).eq(false); - ordersFound.push(selectedOrder); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f"]); - - for (let i = 0; i < 3; i++) { - cy.get( - "#" + cesc2(choiceInputName) + `_choice${i + 1}_input`, - ).click(); - cy.get("#" + cesc2(choiceInputName) + "_submit").click(); - cy.get(cesc("#\\/sr")).should( - "have.text", - choices[choiceOrder[i] - 1], - ); - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - expect( - stateVariables[choiceInputName].stateValues - .selectedValues, - ).eqls([choices[choiceOrder[i] - 1]]); - }); - } - - cy.wait(1500); // wait for 1 second debounce - cy.reload(); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - // wait until core is loaded - cy.waitUntil(() => - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - return stateVariables["/ans"]; - }), - ); - - cy.get(cesc("#\\/sr")).should( - "have.text", - choices[choiceOrder[2] - 1], - ); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables[choiceInputName].stateValues - .selectedValues, - ).eqls([choices[choiceOrder[2] - 1]]); - }); - - cy.get("#" + cesc2(choiceInputName) + `_choice1_input`).click(); - cy.get("#" + cesc2(choiceInputName) + "_submit").click(); - cy.get(cesc("#\\/sr")).should( - "have.text", - choices[choiceOrder[0] - 1], - ); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables[choiceInputName].stateValues - .selectedValues, - ).eqls([choices[choiceOrder[0] - 1]]); - }); - }); - } - - cy.log("7th variant repeats first order"); - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - - let ind = 7; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let choiceInputName = - stateVariables["/ans"].stateValues.inputChildren[0] - .componentName; - let choiceOrder = - stateVariables[choiceInputName].stateValues.choiceOrder; - let selectedOrder = choiceOrder.join(","); - expect(selectedOrder).eq(ordersFound[0]); - }); - }); - - it("shuffled choiceinput with selectFromSequence in choices", () => { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_allowLocalState").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - - let doenetML = ` - - - - - -

Selected value:

- `; - - let selectionsFound = []; - - cy.log("get all options in first 8 variants"); - for (let ind = 1; ind <= 8; ind++) { - if (ind > 1) { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let choiceOrder = stateVariables["/ci"].stateValues.choiceOrder; - let n = stateVariables["/n"].stateValues.value; - let l = stateVariables["/l"].stateValues.value; - let choices = [n.toString(), l]; - let selectedOption = [...choiceOrder, ...choices].join(","); - expect(selectionsFound.includes(selectedOption)).eq(false); - selectionsFound.push(selectedOption); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f", "g", "h"]); - - for (let i = 0; i < 2; i++) { - cy.get(cesc(`#\\/ci_choice${i + 1}_input`)).click(); - cy.get(cesc("#\\/selectedValue")).should( - "have.text", - choices[choiceOrder[i] - 1], - ); - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - expect( - stateVariables["/ci"].stateValues.selectedValues, - ).eqls([choices[choiceOrder[i] - 1]]); - }); - } - - cy.wait(1500); // wait for 1 second debounce - cy.reload(); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - // wait until core is loaded - cy.waitUntil(() => - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - return stateVariables["/ci"]; - }), - ); - - cy.get(cesc("#\\/selectedValue")).should( - "have.text", - choices[choiceOrder[1] - 1], - ); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/ci"].stateValues.selectedValues, - ).eqls([choices[choiceOrder[1] - 1]]); - }); - - cy.get(cesc(`#\\/ci_choice1_input`)).click(); - cy.get(cesc("#\\/selectedValue")).should( - "have.text", - choices[choiceOrder[0] - 1], - ); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/ci"].stateValues.selectedValues, - ).eqls([choices[choiceOrder[0] - 1]]); - }); - }); - } - - cy.log("9th variant repeats first order"); - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - - let ind = 9; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let choiceOrder = stateVariables["/ci"].stateValues.choiceOrder; - let n = stateVariables["/n"].stateValues.value; - let l = stateVariables["/l"].stateValues.value; - let choices = [n.toString(), l]; - let selectedOption = [...choiceOrder, ...choices].join(","); - expect(selectedOption).eq(selectionsFound[0]); - }); - }); - - it("shuffle", () => { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_allowLocalState").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - - let doenetML = ` - -

- red - blue - green -

-

- - `; - - let ordersFound = []; - let colors = ["red", "blue", "green"]; - - cy.log("get all orders in first 6 variants"); - for (let ind = 1; ind <= 6; ind++) { - if (ind > 1) { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let componentOrder = - stateVariables["/sh"].stateValues.componentOrder; - expect([...componentOrder].sort()).eqls([1, 2, 3]); - - let selectedOrder = componentOrder.join(","); - expect(ordersFound.includes(selectedOrder)).eq(false); - ordersFound.push(selectedOrder); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f"]); - - cy.get(cesc("#\\/pList")).should( - "have.text", - componentOrder.map((x) => colors[x - 1]).join(", "), - ); - - // check reloading for just one variant - if (ind === 4) { - cy.get(cesc("#\\/bi")).click(); - cy.get(cesc("#\\/b")).should("have.text", "true"); - - cy.wait(1500); // wait for 1 second debounce - cy.reload(); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.get(cesc("#\\/b")).should("have.text", "true"); - cy.get(cesc("#\\/bi")).click(); - cy.get(cesc("#\\/b")).should("have.text", "false"); - - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - expect( - stateVariables["/sh"].stateValues.componentOrder, - ).eqls(componentOrder); - }); - } - }); - } - - cy.log("7th variant repeats first order"); - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - - let ind = 7; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let componentOrder = - stateVariables["/sh"].stateValues.componentOrder; - let selectedOrder = componentOrder.join(","); - expect(selectedOrder).eq(ordersFound[0]); - - cy.get(cesc("#\\/pList")).should( - "have.text", - componentOrder.map((x) => colors[x - 1]).join(", "), - ); - }); - }); - - it("shuffle, copy in components", () => { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_allowLocalState").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - - let doenetML = ` - - red - - blue - green - -

- - -

-

- - `; - - let ordersFound = []; - let colors = ["red", "blue", "green"]; - - cy.log("get all orders in first 6 variants"); - for (let ind = 1; ind <= 6; ind++) { - if (ind > 1) { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let componentOrder = - stateVariables["/sh"].stateValues.componentOrder; - expect([...componentOrder].sort()).eqls([1, 2, 3]); - - let selectedOrder = componentOrder.join(","); - expect(ordersFound.includes(selectedOrder)).eq(false); - ordersFound.push(selectedOrder); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f"]); - - cy.get(cesc("#\\/pList")).should( - "have.text", - componentOrder.map((x) => colors[x - 1]).join(", "), - ); - - // check reloading for just one variant - if (ind === 4) { - cy.get(cesc("#\\/bi")).click(); - cy.get(cesc("#\\/b")).should("have.text", "true"); - - cy.wait(1500); // wait for 1 second debounce - cy.reload(); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.get(cesc("#\\/b")).should("have.text", "true"); - cy.get(cesc("#\\/bi")).click(); - cy.get(cesc("#\\/b")).should("have.text", "false"); - - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - expect( - stateVariables["/sh"].stateValues.componentOrder, - ).eqls(componentOrder); - }); - } - }); - } - - cy.log("7th variant repeats first order"); - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - - let ind = 7; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let componentOrder = - stateVariables["/sh"].stateValues.componentOrder; - let selectedOrder = componentOrder.join(","); - expect(selectedOrder).eq(ordersFound[0]); - - cy.get(cesc("#\\/pList")).should( - "have.text", - componentOrder.map((x) => colors[x - 1]).join(", "), - ); - }); - }); - - it("document and problems with unique variants", () => { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_allowLocalState").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - - let doenetML = ` - - - -

Enter : - $m -

-
- - -

Enter : - $n -

-
- `; - - cy.log("get all 6 options and then they repeat"); - for (let ind = 1; ind <= 8; ind++) { - if (ind > 1) { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - let m = ((ind - 1) % 2) + 1; - let n = ((ind - 1) % 3) + 3; - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - let mathinputName = cesc2( - stateVariables["/_answer1"].stateValues.inputChildren[0] - .componentName, - ); - let mathinputAnchor = "#" + mathinputName + " textarea"; - let mathinputEditiableFieldAnchor = - "#" + mathinputName + " .mq-editable-field"; - let mathinputSubmitAnchor = "#" + mathinputName + "_submit"; - let mathinputCorrectAnchor = "#" + mathinputName + "_correct"; - let mathinputIncorrectAnchor = - "#" + mathinputName + "_incorrect"; - - let mathinput2Name = cesc2( - stateVariables["/_answer2"].stateValues.inputChildren[0] - .componentName, - ); - let mathinput2Anchor = "#" + mathinput2Name + " textarea"; - let mathinput2EditiableFieldAnchor = - "#" + mathinput2Name + " .mq-editable-field"; - let mathinput2SubmitAnchor = "#" + mathinput2Name + "_submit"; - let mathinput2CorrectAnchor = "#" + mathinput2Name + "_correct"; - let mathinput2IncorrectAnchor = - "#" + mathinput2Name + "_incorrect"; - - expect(stateVariables["/m"].stateValues.value).eq(m); - expect(stateVariables["/n"].stateValues.value).eq(n); - - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f"]); - - cy.get(mathinputAnchor).type(`${m}{enter}`, { force: true }); - cy.get(mathinput2Anchor).type(`${n}{enter}`, { force: true }); - - cy.get(mathinputCorrectAnchor).should("be.visible"); - cy.get(mathinput2CorrectAnchor).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_answer1"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer2"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer1"].stateValues - .submittedResponses, - ).eqls([m]); - expect( - stateVariables["/_answer2"].stateValues - .submittedResponses, - ).eqls([n]); - }); - - cy.wait(1500); // wait for 1 second debounce - cy.reload(); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - // wait until core is loaded - cy.waitUntil(() => - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - return stateVariables["/_answer1"]; - }), - ); - - cy.get(mathinputEditiableFieldAnchor).should( - "contain.text", - `${m}`, - ); - cy.get(mathinput2EditiableFieldAnchor).should( - "contain.text", - `${n}`, - ); - cy.get(mathinputCorrectAnchor).should("be.visible"); - cy.get(mathinput2CorrectAnchor).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_answer1"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer2"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer1"].stateValues - .submittedResponses, - ).eqls([m]); - expect( - stateVariables["/_answer2"].stateValues - .submittedResponses, - ).eqls([n]); - }); - - cy.get(mathinputAnchor).type(`{end}1`, { force: true }); - cy.get(mathinput2Anchor).type(`{end}1`, { force: true }); - cy.get(mathinputSubmitAnchor).click(); - cy.get(mathinput2SubmitAnchor).click(); - cy.get(mathinputIncorrectAnchor).should("be.visible"); - cy.get(mathinput2IncorrectAnchor).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_answer1"].stateValues.creditAchieved, - ).eq(0); - expect( - stateVariables["/_answer2"].stateValues.creditAchieved, - ).eq(0); - expect( - stateVariables["/_answer1"].stateValues - .submittedResponses, - ).eqls([m * 10 + 1]); - expect( - stateVariables["/_answer2"].stateValues - .submittedResponses, - ).eqls([n * 10 + 1]); - }); - - cy.get(mathinputAnchor).type(`{end}{backspace}`, { - force: true, - }); - cy.get(mathinput2Anchor).type(`{end}{backspace}`, { - force: true, - }); - cy.get(mathinputSubmitAnchor).click(); - cy.get(mathinput2SubmitAnchor).click(); - cy.get(mathinputCorrectAnchor).should("be.visible"); - cy.get(mathinput2CorrectAnchor).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_answer1"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer2"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer1"].stateValues - .submittedResponses, - ).eqls([m]); - expect( - stateVariables["/_answer2"].stateValues - .submittedResponses, - ).eqls([n]); - }); - }); - } - }); - - it("problems with unique variants, but not document", () => { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_allowLocalState").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - - let doenetML = ` - - -

Enter : - $m -

-
- - -

Enter : - $n -

-
- `; - - cy.log("get randomly chosen options for each problem"); - for (let ind = 1; ind <= 3; ind++) { - if (ind > 1) { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - } - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - let mathinputName = cesc2( - stateVariables["/_answer1"].stateValues.inputChildren[0] - .componentName, - ); - let mathinputAnchor = "#" + mathinputName + " textarea"; - let mathinputEditiableFieldAnchor = - "#" + mathinputName + " .mq-editable-field"; - let mathinputSubmitAnchor = "#" + mathinputName + "_submit"; - let mathinputCorrectAnchor = "#" + mathinputName + "_correct"; - let mathinputIncorrectAnchor = - "#" + mathinputName + "_incorrect"; - - let mathinput2Name = cesc2( - stateVariables["/_answer2"].stateValues.inputChildren[0] - .componentName, - ); - let mathinput2Anchor = "#" + mathinput2Name + " textarea"; - let mathinput2EditiableFieldAnchor = - "#" + mathinput2Name + " .mq-editable-field"; - let mathinput2SubmitAnchor = "#" + mathinput2Name + "_submit"; - let mathinput2CorrectAnchor = "#" + mathinput2Name + "_correct"; - let mathinput2IncorrectAnchor = - "#" + mathinput2Name + "_incorrect"; - - let m = - stateVariables["/_problem1"].stateValues - .generatedVariantInfo.index; - let n = - stateVariables["/_problem2"].stateValues - .generatedVariantInfo.index + 2; - - expect(m).gte(1); - expect(m).lte(2); - expect(n).gte(3); - expect(n).lte(5); - - expect(stateVariables["/m"].stateValues.value).eq(m); - expect(stateVariables["/n"].stateValues.value).eq(n); - - cy.get(mathinputAnchor).type(`${m}{enter}`, { force: true }); - cy.get(mathinput2Anchor).type(`${n}{enter}`, { force: true }); - - cy.get(mathinputCorrectAnchor).should("be.visible"); - cy.get(mathinput2CorrectAnchor).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_answer1"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer2"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer1"].stateValues - .submittedResponses, - ).eqls([m]); - expect( - stateVariables["/_answer2"].stateValues - .submittedResponses, - ).eqls([n]); - }); - - cy.wait(1500); // wait for 1 second debounce - cy.reload(); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: `${ind}${doenetML}`, - requestedVariantIndex: ind, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - // wait until core is loaded - cy.waitUntil(() => - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - return stateVariables["/_answer1"]; - }), - ); - - cy.get(mathinputEditiableFieldAnchor).should( - "contain.text", - `${m}`, - ); - cy.get(mathinput2EditiableFieldAnchor).should( - "contain.text", - `${n}`, - ); - cy.get(mathinputCorrectAnchor).should("be.visible"); - cy.get(mathinput2CorrectAnchor).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_answer1"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer2"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer1"].stateValues - .submittedResponses, - ).eqls([m]); - expect( - stateVariables["/_answer2"].stateValues - .submittedResponses, - ).eqls([n]); - }); - - cy.get(mathinputAnchor).type(`{end}1`, { force: true }); - cy.get(mathinput2Anchor).type(`{end}1`, { force: true }); - cy.get(mathinputSubmitAnchor).click(); - cy.get(mathinput2SubmitAnchor).click(); - cy.get(mathinputIncorrectAnchor).should("be.visible"); - cy.get(mathinput2IncorrectAnchor).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_answer1"].stateValues.creditAchieved, - ).eq(0); - expect( - stateVariables["/_answer2"].stateValues.creditAchieved, - ).eq(0); - expect( - stateVariables["/_answer1"].stateValues - .submittedResponses, - ).eqls([m * 10 + 1]); - expect( - stateVariables["/_answer2"].stateValues - .submittedResponses, - ).eqls([n * 10 + 1]); - }); - - cy.get(mathinputAnchor).type(`{end}{backspace}`, { - force: true, - }); - cy.get(mathinput2Anchor).type(`{end}{backspace}`, { - force: true, - }); - cy.get(mathinputSubmitAnchor).click(); - cy.get(mathinput2SubmitAnchor).click(); - cy.get(mathinputCorrectAnchor).should("be.visible"); - cy.get(mathinput2CorrectAnchor).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_answer1"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer2"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer1"].stateValues - .submittedResponses, - ).eqls([m]); - expect( - stateVariables["/_answer2"].stateValues - .submittedResponses, - ).eqls([n]); - }); - }); - } - }); - - it("document inherits variants from single problem with unique variants", () => { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_allowLocalState").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - - cy.log("get all 3 options and then they repeat"); - for (let ind = 1; ind <= 4; ind++) { - if (ind > 1) { - cy.get("#testRunner_toggleControls").click(); - cy.get("#testRunner_newAttempt").click(); - cy.wait(100); - cy.get("#testRunner_toggleControls").click(); - cy.reload(); - } - - let doenetML = ` - - -

Enter : - $m -

- ${ind} -
- `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - let m = ((ind - 1) % 3) + 5; - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - let mathinputName = cesc2( - stateVariables["/_answer1"].stateValues.inputChildren[0] - .componentName, - ); - let mathinputAnchor = "#" + mathinputName + " textarea"; - let mathinputEditiableFieldAnchor = - "#" + mathinputName + " .mq-editable-field"; - let mathinputSubmitAnchor = "#" + mathinputName + "_submit"; - let mathinputCorrectAnchor = "#" + mathinputName + "_correct"; - let mathinputIncorrectAnchor = - "#" + mathinputName + "_incorrect"; - - expect(stateVariables["/m"].stateValues.value).eq(m); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["five", "six", "seven"]); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq(["five", "six", "seven"][(ind - 1) % 3]); - - cy.get(mathinputAnchor).type(`${m}{enter}`, { force: true }); - - cy.get(mathinputCorrectAnchor).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_answer1"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer1"].stateValues - .submittedResponses, - ).eqls([m]); - }); - - cy.wait(1500); // wait for 1 second debounce - cy.reload(); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML, - requestedVariantIndex: ind, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - // wait until core is loaded - cy.waitUntil(() => - cy.window().then(async (win) => { - let stateVariables = - await win.returnAllStateVariables1(); - return stateVariables["/_answer1"]; - }), - ); - - cy.get(mathinputEditiableFieldAnchor).should( - "contain.text", - `${m}`, - ); - cy.get(mathinputCorrectAnchor).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_answer1"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer1"].stateValues - .submittedResponses, - ).eqls([m]); - }); - - cy.get(mathinputAnchor).type(`{end}1`, { force: true }); - cy.get(mathinputSubmitAnchor).click(); - cy.get(mathinputIncorrectAnchor).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_answer1"].stateValues.creditAchieved, - ).eq(0); - expect( - stateVariables["/_answer1"].stateValues - .submittedResponses, - ).eqls([m * 10 + 1]); - }); - - cy.get(mathinputAnchor).type(`{end}{backspace}`, { - force: true, - }); - cy.get(mathinputSubmitAnchor).click(); - cy.get(mathinputCorrectAnchor).should("be.visible"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_answer1"].stateValues.creditAchieved, - ).eq(1); - expect( - stateVariables["/_answer1"].stateValues - .submittedResponses, - ).eqls([m]); - }); - }); - } - }); - - it("no variant control, 1 unique variant", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - hello! - `, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `a`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a"]); - }); - }); - - it("no variant control, single select", () => { - let values = ["u", "v", "w"]; - - cy.log("get all values in order and they repeat in next variants"); - for (let ind = 1; ind <= 4; ind++) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.get(cesc("#\\/x") + " .mjx-mrow").should( - "have.text", - values[(ind - 1) % 3], - ); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/x"].stateValues.value).eq( - values[(ind - 1) % 3], - ); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c"]); - }); - } - }); - - it("no variant control, select and selectFromSequence", () => { - let values = ["u", "v", "w"]; - - cy.log("get first values in order"); - for (let ind = 1; ind <= 3; ind++) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.get(cesc("#\\/x") + " .mjx-mrow").should( - "have.text", - values[ind - 1], - ); - cy.get(cesc("#\\/n")).should("have.text", ind.toString()); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/x"].stateValues.value).eq( - values[ind - 1], - ); - expect(stateVariables["/n"].stateValues.value).eq(ind); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants.length, - ).eq(30); - }); - } - }); - - it("no variant control, 100 is still unique variants", () => { - cy.log("get first values in order"); - for (let ind = 1; ind <= 5; ind++) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.get(cesc("#\\/n")).should("have.text", ind.toString()); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(ind); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants.length, - ).eq(100); - }); - } - }); - - it("no variant control, 101 is not unique variants", () => { - let foundOneNotInOrder = false; - - cy.log("don't get first values in order"); - for (let ind = 1; ind <= 3; ind++) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - if (stateVariables["/n"].stateValues.value !== ind) { - foundOneNotInOrder = true; - } - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants.length, - ).eq(100); - }); - } - - cy.window().then(async (win) => { - expect(foundOneNotInOrder).eq(true); - }); - }); - - it("no variant control, problem with 3 selects", () => { - // Catch bug in enumerateCombinations - // where was indirectly overwriting numVariantsByDescendant - let values = [135, 246, 145, 236, 136, 245, 146, 235]; - - cy.log("get each value exactly one"); - let valuesFound = []; - for (let ind = 1; ind <= 8; ind++) { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - ${ind} - - - - - - `, - requestedVariantIndex: ind, - }, - "*", - ); - }); - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", `${ind}`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let a = stateVariables["/a"].stateValues.value; - let b = stateVariables["/b"].stateValues.value; - let c = stateVariables["/c"].stateValues.value; - - let val = a * 100 + b * 10 + c; - valuesFound.push(val); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants.length, - ).eq(8); - - cy.get(cesc("#\\/a")).should("have.text", a.toString()); - cy.get(cesc("#\\/b")).should("have.text", b.toString()); - cy.get(cesc("#\\/c")).should("have.text", c.toString()); - }); - } - cy.window().then((win) => { - expect([...valuesFound].sort((a, b) => a - b)).eqls( - [...values].sort((a, b) => a - b), - ); - }); - }); - - it("variantsToInclude and variantsToExclude", () => { - cy.log("get two variants with no include/exclude"); - - let baseDoenetMLa = ` - - Selected number: - - `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: "2 { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: "5 { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.log("get same variants when add variantsToInclude"); - - let baseDoenetMLb = ` - - Selected number: - - `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: "1 { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: "2 { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.log("get same variants when add variantsToExclude"); - - let baseDoenetMLc = ` - - Selected number: - - `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: "1 { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "c", "e", "f", "g", "i"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: "3 { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(3); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "c", "e", "f", "g", "i"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.log( - "get same variants when add variantsToInclude and variantsToExclude", - ); - - let baseDoenetMLd = ` - - Selected number: - - `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: "1 { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e", "g"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: "2 { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e", "g"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - }); - - it("variantsToInclude and variantsToExclude in problem as only child", () => { - cy.log("get two variants with no include/exclude"); - - let baseDoenetMLa = ` - - - Selected number: - - - `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLa, - requestedVariantIndex: 2, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `2`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLa, - requestedVariantIndex: 5, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `5`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(5); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.log("get same variants when add variantsToInclude"); - - let baseDoenetMLb = ` - - - Selected number: - - - `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLb, - requestedVariantIndex: 1, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `2`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("1"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLb, - requestedVariantIndex: 2, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `5`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.log("get same variants when add variantsToExclude"); - - let baseDoenetMLc = ` - - - Selected number: - - - `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLc, - requestedVariantIndex: 1, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `2`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("1"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "c", "e", "f", "g", "i"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "c", "e", "f", "g", "i"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLc, - requestedVariantIndex: 3, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `5`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("3"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(3); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "c", "e", "f", "g", "i"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(3); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "c", "e", "f", "g", "i"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.log( - "get same variants when add variantsToInclude and variantsToExclude", - ); - - let baseDoenetMLd = ` - - - Selected number: - - - `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLd, - requestedVariantIndex: 1, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `2`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("1"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e", "g"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e", "g"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLd, - requestedVariantIndex: 2, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `5`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e", "g"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e", "g"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - }); - - it("variantsToInclude and variantsToExclude in problem, extra child", () => { - cy.log("get two variants with no include/exclude"); - - let baseDoenetMLa = ` - Hello! - - - Selected number: - - - `; - - let allDocVariants = [ - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "aa", - "ab", - "ac", - "ad", - "ae", - "af", - "ag", - "ah", - "ai", - "aj", - "ak", - "al", - "am", - "an", - "ao", - "ap", - "aq", - "ar", - "as", - "at", - "au", - "av", - "aw", - "ax", - "ay", - "az", - "ba", - "bb", - "bc", - "bd", - "be", - "bf", - "bg", - "bh", - "bi", - "bj", - "bk", - "bl", - "bm", - "bn", - "bo", - "bp", - "bq", - "br", - "bs", - "bt", - "bu", - "bv", - "bw", - "bx", - "by", - "bz", - "ca", - "cb", - "cc", - "cd", - "ce", - "cf", - "cg", - "ch", - "ci", - "cj", - "ck", - "cl", - "cm", - "cn", - "co", - "cp", - "cq", - "cr", - "cs", - "ct", - "cu", - "cv", - ]; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLa, - requestedVariantIndex: 2, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `2`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("b"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(allDocVariants); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLa, - requestedVariantIndex: 5, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `5`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(allDocVariants); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(5); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.log("get same variants when add variantsToInclude"); - - let baseDoenetMLb = ` - Hello! - - - Selected number: - - - `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLb, - requestedVariantIndex: 1, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `2`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("1"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("a"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(allDocVariants); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLb, - requestedVariantIndex: 2, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `5`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("b"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(allDocVariants); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.log("get same variants when add variantsToExclude"); - - let baseDoenetMLc = ` - Hello! - - - Selected number: - - - `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLc, - requestedVariantIndex: 1, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `2`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("1"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("a"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(allDocVariants); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "c", "e", "f", "g", "i"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLc, - requestedVariantIndex: 3, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `5`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("3"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(3); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("c"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c", "d", "e", "f"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(allDocVariants); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(3); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "c", "e", "f", "g", "i"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.log( - "get same variants when add variantsToInclude and variantsToExclude", - ); - - let baseDoenetMLd = ` - Hello! - - - Selected number: - - - `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLd, - requestedVariantIndex: 1, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `2`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("1"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("a"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(allDocVariants); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("second"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e", "g"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: baseDoenetMLd, - requestedVariantIndex: 2, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/n")).should("have.text", `5`); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(5); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("2"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("b"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["a", "b", "c"]); - expect( - stateVariables["/_document1"].sharedParameters.allVariantNames, - ).eqls(allDocVariants); - expect( - stateVariables["/_problem1"].sharedParameters.variantSeed, - ).eq("5"); - expect( - stateVariables["/_problem1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_problem1"].sharedParameters.variantName, - ).eq("e"); - expect( - stateVariables["/_problem1"].sharedParameters - .allPossibleVariants, - ).eqls(["second", "e", "g"]); - expect( - stateVariables["/_problem1"].sharedParameters.allVariantNames, - ).eqls(["first", "second", "c", "d", "e", "f", "g", "h", "i", "j"]); - }); - }); - - it("unique variants determined by numVariants specified, even with variantsToInclude and variantsToExclude", () => { - cy.log("unique variants when numVariants is 1000"); - - let baseDoenetMLa = ` - - Selected number: - - `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: "1 { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(20); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("20"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("t"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["t", "cv"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: "2 { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).eq(100); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("100"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("cv"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["t", "cv"]); - }); - - cy.log("non-unique variants when numVariants is 100"); - - let baseDoenetMLb = ` - - Selected number: - - `; - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: "1 { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).not.eq(20); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("20"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(1); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("t"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["t", "cv"]); - }); - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: "2 { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/n"].stateValues.value).not.eq(100); - expect( - stateVariables["/_document1"].sharedParameters.variantSeed, - ).eq("100"); - expect( - stateVariables["/_document1"].sharedParameters.variantIndex, - ).eq(2); - expect( - stateVariables["/_document1"].sharedParameters.variantName, - ).eq("cv"); - expect( - stateVariables["/_document1"].sharedParameters - .allPossibleVariants, - ).eqls(["t", "cv"]); - }); - }); -});