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 = `
+
+
+ `;
+ // 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 = `
+
+
+ `;
+ // 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 = `
+
+
+
+
+ `;
+
+ // 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 = `
+
+
+
+ Favorite color
+
+
+ I like
+ red orange yellow magenta maroon fuchsia scarlet
+
+
+
+ You like
+ green chartreuse turquoise
+
+
+
+ Enter the color $(p/color): $(p/color)
+
+
+
+ Selected word
+
+ Verb: run walk jump skip
+ Adjective: soft scary large empty residual limitless
+
+ Enter the word $(p/word): $(p/word)
+
+
+
+ Chosen letter
+ Letter
+
+
+ Enter the letter $l: $l
+
+
+
+ `;
+
+ 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 = `u v w`;
+ 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 = `
+ u v w
+
+ `;
+ 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 = `
+
+ 1 2
+ 3 4
+ 5 6
+
+ `;
+
+ 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:
- Enter $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}
-
- u v w x y z
- `,
- 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}
-
-
-
- x y z
-
- 3 7
-
- `,
- 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}
-
-
-
- x y z
-
- 3 7
-
- `,
- 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}
-
-
- w x y z
-
- `,
- 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}
-
-
- w x y z
-
- `,
- 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}
-
-
- x y z
-
- `,
- 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}
-
-
- x y z
-
- `,
- 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
-
-
- 101 102 103
-
-
- 201 202 203 204
-
-
- `,
- 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
-
-
- 101 102 103
-
-
- 201 202 203 204
-
-
- `,
- 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
-
-
-
-
-
- 201 202 203 204
-
-
- `,
- 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
-
-
-
-
-
- 201 202 203 204
-
-
- `,
- 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
-
-
- 101 102 103
-
-
- 201 202 203 204
-
-
-
- `,
- 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
-
-
- 101 102 103
-
-
- 201 202 203 204
-
-
-
- `,
- 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
-
-
- 101 102 103
-
-
- 201 202 203 204
-
-
-
- `,
- 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 = `
-
-
-
- Favorite color:
-
-
- red orange yellow magenta maroon fuchsia scarlet
-
-
- green chartreuse turquoise
-
-
- white black
-
-
-
-
-
- Selected number:
-
-
-
-
-
-
-
- Chosen letter:
-
-
- Variable:
- u v w x y z
-
-
-
- `;
-
- 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 = `
-
-
-
- Favorite color
-
-
- I like
- red orange yellow magenta maroon fuchsia scarlet
-
-
-
- You like
- green chartreuse turquoise
-
-
-
- Enter the color $(p/color): $(p/color)
-
-
-
- Selected word
-
- Verb: run walk jump skip
- Adjective: soft scary large empty residual limitless
-
- Enter the word $(p/word): $(p/word)
-
-
-
- Chosen letter
- Letter
-
-
- Enter the letter $l: $l
-
-
-
- `;
-
- 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}
- u v w
- `,
- 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}
- u v w
-
- `,
- 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}
-
- 1 2
- 3 4
- 5 6
-
- `,
- 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"]);
- });
- });
-});