@doenet/doenetml 0.6.0-alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (549) hide show
  1. package/.prettierrc +3 -0
  2. package/LICENSE +661 -0
  3. package/README.md +146 -0
  4. package/cypress/e2e/ActivityViewer/activityVariants.cy.js +1770 -0
  5. package/cypress/e2e/ActivityViewer/compiledActivity.cy.js +83 -0
  6. package/cypress/e2e/ActivityViewer/relationshipsAmongPages.cy.js +697 -0
  7. package/cypress/e2e/answerValidation/errorinnumbers.cy.js +2125 -0
  8. package/cypress/e2e/answerValidation/factoring.cy.js +1945 -0
  9. package/cypress/e2e/answerValidation/factoringOldAlgorithm.cy.js +892 -0
  10. package/cypress/e2e/answerValidation/functionanswers.cy.js +314 -0
  11. package/cypress/e2e/answerValidation/matchingpatterns.cy.js +287 -0
  12. package/cypress/e2e/answerValidation/matchpartial.cy.js +6711 -0
  13. package/cypress/e2e/answerValidation/pointlocation.cy.js +3989 -0
  14. package/cypress/e2e/answerValidation/symbolicequality.cy.js +1893 -0
  15. package/cypress/e2e/answerValidation/videoProgress.cy.js +210 -0
  16. package/cypress/e2e/assignNames/basiccopy.cy.js +2376 -0
  17. package/cypress/e2e/assignNames/collections.cy.js +9247 -0
  18. package/cypress/e2e/assignNames/selects.cy.js +105 -0
  19. package/cypress/e2e/assignNames/sequences.cy.js +1964 -0
  20. package/cypress/e2e/baseComponent/basecomponentproperties.cy.js +999 -0
  21. package/cypress/e2e/baseComponent/doenetMLtext.cy.js +427 -0
  22. package/cypress/e2e/chemistry/atom.cy.js +201 -0
  23. package/cypress/e2e/chemistry/ion.cy.js +608 -0
  24. package/cypress/e2e/chemistry/ioniccompound.cy.js +133 -0
  25. package/cypress/e2e/dynamicalsystem/cobwebpolyline.cy.js +2653 -0
  26. package/cypress/e2e/dynamicalsystem/equilibriumcurve.cy.js +311 -0
  27. package/cypress/e2e/dynamicalsystem/equilibriumline.cy.js +279 -0
  28. package/cypress/e2e/dynamicalsystem/equilibriumpoint.cy.js +283 -0
  29. package/cypress/e2e/dynamicalsystem/odesystem.cy.js +1834 -0
  30. package/cypress/e2e/equality/mathexpressions.cy.js +948 -0
  31. package/cypress/e2e/graphing/graphreferences.cy.js +978 -0
  32. package/cypress/e2e/graphing/graphreferences2.cy.js +615 -0
  33. package/cypress/e2e/linearAlgebra/eigenDecomposition.cy.js +401 -0
  34. package/cypress/e2e/tagSpecific/angle.cy.js +3898 -0
  35. package/cypress/e2e/tagSpecific/animatefromsequence.cy.js +2306 -0
  36. package/cypress/e2e/tagSpecific/answer.cy.js +31647 -0
  37. package/cypress/e2e/tagSpecific/bestfitline.cy.js +612 -0
  38. package/cypress/e2e/tagSpecific/blockquote.cy.js +30 -0
  39. package/cypress/e2e/tagSpecific/boolean.cy.js +742 -0
  40. package/cypress/e2e/tagSpecific/booleaninput.cy.js +1283 -0
  41. package/cypress/e2e/tagSpecific/booleanlist.cy.js +588 -0
  42. package/cypress/e2e/tagSpecific/booleanoperators.cy.js +596 -0
  43. package/cypress/e2e/tagSpecific/booleanoperatorsonmath.cy.js +498 -0
  44. package/cypress/e2e/tagSpecific/callaction.cy.js +2835 -0
  45. package/cypress/e2e/tagSpecific/choiceinput.cy.js +3205 -0
  46. package/cypress/e2e/tagSpecific/circle.cy.js +22036 -0
  47. package/cypress/e2e/tagSpecific/codeeditor.cy.js +1995 -0
  48. package/cypress/e2e/tagSpecific/collect.cy.js +5035 -0
  49. package/cypress/e2e/tagSpecific/componentsize.cy.js +502 -0
  50. package/cypress/e2e/tagSpecific/conditionalcontent.cy.js +3495 -0
  51. package/cypress/e2e/tagSpecific/contentBrowser.cy.js +335 -0
  52. package/cypress/e2e/tagSpecific/contentpicker.cy.js +261 -0
  53. package/cypress/e2e/tagSpecific/copy.cy.js +12627 -0
  54. package/cypress/e2e/tagSpecific/copy2.cy.js +5698 -0
  55. package/cypress/e2e/tagSpecific/curve.bezier.cy.js +12440 -0
  56. package/cypress/e2e/tagSpecific/curve.cy.js +1716 -0
  57. package/cypress/e2e/tagSpecific/curve.function.cy.js +1471 -0
  58. package/cypress/e2e/tagSpecific/curve.parametrized.cy.js +920 -0
  59. package/cypress/e2e/tagSpecific/document.cy.js +234 -0
  60. package/cypress/e2e/tagSpecific/endpoint.cy.js +197 -0
  61. package/cypress/e2e/tagSpecific/evaluate.cy.js +8895 -0
  62. package/cypress/e2e/tagSpecific/extract.cy.js +2282 -0
  63. package/cypress/e2e/tagSpecific/feedback.cy.js +2941 -0
  64. package/cypress/e2e/tagSpecific/function.cy.js +9450 -0
  65. package/cypress/e2e/tagSpecific/functioniterates.cy.js +1178 -0
  66. package/cypress/e2e/tagSpecific/functionoperators.cy.js +4047 -0
  67. package/cypress/e2e/tagSpecific/graph.cy.js +2491 -0
  68. package/cypress/e2e/tagSpecific/group.cy.js +683 -0
  69. package/cypress/e2e/tagSpecific/hint.cy.js +204 -0
  70. package/cypress/e2e/tagSpecific/image.cy.js +770 -0
  71. package/cypress/e2e/tagSpecific/integer.cy.js +206 -0
  72. package/cypress/e2e/tagSpecific/label.cy.js +800 -0
  73. package/cypress/e2e/tagSpecific/legend.cy.js +1001 -0
  74. package/cypress/e2e/tagSpecific/line.cy.js +12167 -0
  75. package/cypress/e2e/tagSpecific/linesegment.cy.js +4749 -0
  76. package/cypress/e2e/tagSpecific/lorem.cy.js +289 -0
  77. package/cypress/e2e/tagSpecific/map.cy.js +4476 -0
  78. package/cypress/e2e/tagSpecific/matchespattern.cy.js +693 -0
  79. package/cypress/e2e/tagSpecific/math.cy.js +10990 -0
  80. package/cypress/e2e/tagSpecific/mathdisplay.cy.js +2689 -0
  81. package/cypress/e2e/tagSpecific/mathinput.cy.js +15628 -0
  82. package/cypress/e2e/tagSpecific/mathinputgraph.cy.js +566 -0
  83. package/cypress/e2e/tagSpecific/mathlist.cy.js +4073 -0
  84. package/cypress/e2e/tagSpecific/mathoperators.cy.js +13851 -0
  85. package/cypress/e2e/tagSpecific/matrix.cy.js +8825 -0
  86. package/cypress/e2e/tagSpecific/matrixinput.cy.js +16277 -0
  87. package/cypress/e2e/tagSpecific/module.cy.js +1771 -0
  88. package/cypress/e2e/tagSpecific/number.cy.js +2221 -0
  89. package/cypress/e2e/tagSpecific/numberlist.cy.js +1285 -0
  90. package/cypress/e2e/tagSpecific/p.cy.js +72 -0
  91. package/cypress/e2e/tagSpecific/paginator.cy.js +2983 -0
  92. package/cypress/e2e/tagSpecific/parabola.cy.js +14331 -0
  93. package/cypress/e2e/tagSpecific/paragraphmarkup.cy.js +104 -0
  94. package/cypress/e2e/tagSpecific/periodicset.cy.js +1439 -0
  95. package/cypress/e2e/tagSpecific/piecewisefunction.cy.js +1055 -0
  96. package/cypress/e2e/tagSpecific/pluralize.cy.js +274 -0
  97. package/cypress/e2e/tagSpecific/point.cy.js +8895 -0
  98. package/cypress/e2e/tagSpecific/point2.cy.js +10259 -0
  99. package/cypress/e2e/tagSpecific/polygon.cy.js +5039 -0
  100. package/cypress/e2e/tagSpecific/polyline.cy.js +4704 -0
  101. package/cypress/e2e/tagSpecific/problem.cy.js +2768 -0
  102. package/cypress/e2e/tagSpecific/ray.cy.js +10770 -0
  103. package/cypress/e2e/tagSpecific/rectangle.cy.js +2143 -0
  104. package/cypress/e2e/tagSpecific/ref.cy.js +420 -0
  105. package/cypress/e2e/tagSpecific/regularPolygon.cy.js +1006 -0
  106. package/cypress/e2e/tagSpecific/regularPolygon2.cy.js +100 -0
  107. package/cypress/e2e/tagSpecific/regularPolygon3.cy.js +777 -0
  108. package/cypress/e2e/tagSpecific/samplerandomnumbers.cy.js +3619 -0
  109. package/cypress/e2e/tagSpecific/sectioning.cy.js +3530 -0
  110. package/cypress/e2e/tagSpecific/select.cy.js +5376 -0
  111. package/cypress/e2e/tagSpecific/selectfromsequence.cy.js +3846 -0
  112. package/cypress/e2e/tagSpecific/selectrandomnumbers.cy.js +2914 -0
  113. package/cypress/e2e/tagSpecific/sequence.cy.js +2093 -0
  114. package/cypress/e2e/tagSpecific/shuffle.cy.js +490 -0
  115. package/cypress/e2e/tagSpecific/sidebyside.cy.js +8057 -0
  116. package/cypress/e2e/tagSpecific/singlecharactercomponents.cy.js +72 -0
  117. package/cypress/e2e/tagSpecific/slider.cy.js +914 -0
  118. package/cypress/e2e/tagSpecific/solution.cy.js +109 -0
  119. package/cypress/e2e/tagSpecific/solveequations.cy.js +1026 -0
  120. package/cypress/e2e/tagSpecific/sort.cy.js +1685 -0
  121. package/cypress/e2e/tagSpecific/spreadsheet.cy.js +5971 -0
  122. package/cypress/e2e/tagSpecific/subsetofreals.cy.js +2725 -0
  123. package/cypress/e2e/tagSpecific/substitute.cy.js +2646 -0
  124. package/cypress/e2e/tagSpecific/tabular.cy.js +36 -0
  125. package/cypress/e2e/tagSpecific/text.cy.js +975 -0
  126. package/cypress/e2e/tagSpecific/textinput.cy.js +2177 -0
  127. package/cypress/e2e/tagSpecific/textlist.cy.js +369 -0
  128. package/cypress/e2e/tagSpecific/triangle.cy.js +1936 -0
  129. package/cypress/e2e/tagSpecific/triggerset.cy.js +2023 -0
  130. package/cypress/e2e/tagSpecific/updatevalue.cy.js +3288 -0
  131. package/cypress/e2e/tagSpecific/vector.cy.js +20183 -0
  132. package/cypress/e2e/tagSpecific/video.cy.js +612 -0
  133. package/cypress/e2e/tagSpecific/when.cy.js +202 -0
  134. package/cypress/e2e/variants/specifysinglevariant.cy.js +6726 -0
  135. package/cypress/e2e/variants/uniquevariants.cy.js +4846 -0
  136. package/cypress/fixtures/example.json +5 -0
  137. package/cypress/support/commands.js +32 -0
  138. package/cypress/support/e2e.js +31 -0
  139. package/cypress.config.js +18 -0
  140. package/docs/codeSnippet.jsx +11 -0
  141. package/docs/index.html +133 -0
  142. package/docs/index.jsx +138 -0
  143. package/docs/prism.css +3 -0
  144. package/index.html +14 -0
  145. package/index.js +21 -0
  146. package/media/answer_example.png +0 -0
  147. package/media/graph_example.png +0 -0
  148. package/media/graph_markup_example.png +0 -0
  149. package/package.json +83 -0
  150. package/public/favicon.ico +0 -0
  151. package/public/fonts/files/open-sans-v18-latin-700.woff +0 -0
  152. package/public/fonts/files/open-sans-v18-latin-700.woff2 +0 -0
  153. package/public/fonts/files/open-sans-v18-latin-700italic.woff +0 -0
  154. package/public/fonts/files/open-sans-v18-latin-700italic.woff2 +0 -0
  155. package/public/fonts/files/open-sans-v18-latin-italic.woff +0 -0
  156. package/public/fonts/files/open-sans-v18-latin-italic.woff2 +0 -0
  157. package/public/fonts/files/open-sans-v18-latin-light-italic.woff +0 -0
  158. package/public/fonts/files/open-sans-v18-latin-light-italic.woff2 +0 -0
  159. package/public/fonts/files/open-sans-v18-latin-light.woff +0 -0
  160. package/public/fonts/files/open-sans-v18-latin-light.woff2 +0 -0
  161. package/public/fonts/files/open-sans-v18-latin-regular.woff +0 -0
  162. package/public/fonts/files/open-sans-v18-latin-regular.woff2 +0 -0
  163. package/src/Core/ComponentTypes.js +426 -0
  164. package/src/Core/Core.js +11852 -0
  165. package/src/Core/CoreWorker.js +127 -0
  166. package/src/Core/Dependencies.js +8226 -0
  167. package/src/Core/Numerics.js +473 -0
  168. package/src/Core/ParameterStack.js +36 -0
  169. package/src/Core/ReadOnlyProxyHandler.js +41 -0
  170. package/src/Core/StateProxyHandler.js +88 -0
  171. package/src/Core/components/Aliases.js +67 -0
  172. package/src/Core/components/Angle.js +758 -0
  173. package/src/Core/components/AnimateFromSequence.js +922 -0
  174. package/src/Core/components/Answer.js +2087 -0
  175. package/src/Core/components/AsList.js +83 -0
  176. package/src/Core/components/AttractTo.js +245 -0
  177. package/src/Core/components/AttractToAngles.js +262 -0
  178. package/src/Core/components/AttractToConstraint.js +104 -0
  179. package/src/Core/components/AttractToGrid.js +315 -0
  180. package/src/Core/components/Award.js +906 -0
  181. package/src/Core/components/BestFitLine.js +318 -0
  182. package/src/Core/components/BezierControls.js +719 -0
  183. package/src/Core/components/BlockQuote.js +35 -0
  184. package/src/Core/components/Boolean.js +500 -0
  185. package/src/Core/components/BooleanInput.js +330 -0
  186. package/src/Core/components/BooleanList.js +396 -0
  187. package/src/Core/components/BooleanOperators.js +35 -0
  188. package/src/Core/components/BooleanOperatorsOfMath.js +148 -0
  189. package/src/Core/components/CallAction.js +261 -0
  190. package/src/Core/components/Caption.js +73 -0
  191. package/src/Core/components/Case.js +56 -0
  192. package/src/Core/components/Cell.js +439 -0
  193. package/src/Core/components/CellBlock.js +64 -0
  194. package/src/Core/components/Chart.js +795 -0
  195. package/src/Core/components/Choice.js +266 -0
  196. package/src/Core/components/ChoiceInput.js +1407 -0
  197. package/src/Core/components/Circle.js +2884 -0
  198. package/src/Core/components/CodeEditor.js +647 -0
  199. package/src/Core/components/CodeViewer.js +294 -0
  200. package/src/Core/components/CollaborateGroupSetup.js +46 -0
  201. package/src/Core/components/CollaborateGroups.js +119 -0
  202. package/src/Core/components/Collect.js +850 -0
  203. package/src/Core/components/Column.js +608 -0
  204. package/src/Core/components/ConditionalContent.js +468 -0
  205. package/src/Core/components/ConsiderAsResponses.js +49 -0
  206. package/src/Core/components/ConstrainTo.js +161 -0
  207. package/src/Core/components/ConstrainToAngles.js +244 -0
  208. package/src/Core/components/ConstrainToGraph.js +142 -0
  209. package/src/Core/components/ConstrainToGrid.js +175 -0
  210. package/src/Core/components/ConstraintUnion.js +119 -0
  211. package/src/Core/components/Constraints.js +497 -0
  212. package/src/Core/components/ContentBrowser.js +441 -0
  213. package/src/Core/components/ContentPicker.js +263 -0
  214. package/src/Core/components/ControlVectors.js +25 -0
  215. package/src/Core/components/Coords.js +63 -0
  216. package/src/Core/components/Copy.js +3412 -0
  217. package/src/Core/components/Curve.js +4130 -0
  218. package/src/Core/components/CustomAttribute.js +175 -0
  219. package/src/Core/components/DataFrame.js +357 -0
  220. package/src/Core/components/DiscreteSimulationResultList.js +342 -0
  221. package/src/Core/components/DiscreteSimulationResultPolyline.js +581 -0
  222. package/src/Core/components/Divisions.js +55 -0
  223. package/src/Core/components/Document.js +888 -0
  224. package/src/Core/components/Embed.js +65 -0
  225. package/src/Core/components/Endpoint.js +62 -0
  226. package/src/Core/components/Evaluate.js +321 -0
  227. package/src/Core/components/Extract.js +656 -0
  228. package/src/Core/components/Extrema.js +556 -0
  229. package/src/Core/components/Feedback.js +200 -0
  230. package/src/Core/components/FeedbackDefinitions.js +97 -0
  231. package/src/Core/components/Figure.js +148 -0
  232. package/src/Core/components/Footnote.js +73 -0
  233. package/src/Core/components/Function.js +5344 -0
  234. package/src/Core/components/FunctionIterates.js +306 -0
  235. package/src/Core/components/FunctionOperators.js +702 -0
  236. package/src/Core/components/Graph.js +1679 -0
  237. package/src/Core/components/Group.js +7 -0
  238. package/src/Core/components/HasSameFactoring.js +407 -0
  239. package/src/Core/components/Hint.js +241 -0
  240. package/src/Core/components/Image.js +524 -0
  241. package/src/Core/components/Indexing.js +79 -0
  242. package/src/Core/components/IntComma.js +64 -0
  243. package/src/Core/components/Integer.js +81 -0
  244. package/src/Core/components/Intersection.js +328 -0
  245. package/src/Core/components/Interval.js +29 -0
  246. package/src/Core/components/Label.js +492 -0
  247. package/src/Core/components/Latex.js +104 -0
  248. package/src/Core/components/Legend.js +329 -0
  249. package/src/Core/components/Line.js +2040 -0
  250. package/src/Core/components/LineSegment.js +882 -0
  251. package/src/Core/components/Lists.js +180 -0
  252. package/src/Core/components/Lorem.js +249 -0
  253. package/src/Core/components/MMeMen.js +377 -0
  254. package/src/Core/components/Map.js +873 -0
  255. package/src/Core/components/Markers.js +101 -0
  256. package/src/Core/components/MatchesPattern.js +339 -0
  257. package/src/Core/components/Math.js +2552 -0
  258. package/src/Core/components/MathInput.js +948 -0
  259. package/src/Core/components/MathList.js +828 -0
  260. package/src/Core/components/MathOperators.js +1286 -0
  261. package/src/Core/components/Matrix.js +497 -0
  262. package/src/Core/components/MatrixInput.js +3157 -0
  263. package/src/Core/components/MdMdnMrow.js +394 -0
  264. package/src/Core/components/Module.js +16 -0
  265. package/src/Core/components/Number.js +1031 -0
  266. package/src/Core/components/NumberList.js +550 -0
  267. package/src/Core/components/Option.js +24 -0
  268. package/src/Core/components/P.js +71 -0
  269. package/src/Core/components/Paginator.js +338 -0
  270. package/src/Core/components/Panel.js +126 -0
  271. package/src/Core/components/Parabola.js +1561 -0
  272. package/src/Core/components/ParagraphMarkup.js +59 -0
  273. package/src/Core/components/Pegboard.js +43 -0
  274. package/src/Core/components/PeriodicSet.js +291 -0
  275. package/src/Core/components/PiecewiseFunction.js +832 -0
  276. package/src/Core/components/Pluralize.js +198 -0
  277. package/src/Core/components/Point.js +1295 -0
  278. package/src/Core/components/Polygon.js +408 -0
  279. package/src/Core/components/Polyline.js +841 -0
  280. package/src/Core/components/RandomizedTextList.js +225 -0
  281. package/src/Core/components/Ray.js +1737 -0
  282. package/src/Core/components/Rectangle.js +1535 -0
  283. package/src/Core/components/Ref.js +350 -0
  284. package/src/Core/components/RegionBetweenCurveXAxis.js +124 -0
  285. package/src/Core/components/RegionHalfPlane.js +107 -0
  286. package/src/Core/components/RegularPolygon.js +2118 -0
  287. package/src/Core/components/RenderDoenetML.js +181 -0
  288. package/src/Core/components/Row.js +780 -0
  289. package/src/Core/components/SampleRandomNumbers.js +653 -0
  290. package/src/Core/components/Sectioning.js +303 -0
  291. package/src/Core/components/Select.js +947 -0
  292. package/src/Core/components/SelectFromSequence.js +1242 -0
  293. package/src/Core/components/SelectRandomNumbers.js +225 -0
  294. package/src/Core/components/Sequence.js +444 -0
  295. package/src/Core/components/Setup.js +53 -0
  296. package/src/Core/components/Shuffle.js +470 -0
  297. package/src/Core/components/SideBySide.js +2130 -0
  298. package/src/Core/components/SingleCharacterComponents.js +41 -0
  299. package/src/Core/components/Slider.js +819 -0
  300. package/src/Core/components/SolutionContainer.js +67 -0
  301. package/src/Core/components/Solutions.js +334 -0
  302. package/src/Core/components/SolveEquations.js +568 -0
  303. package/src/Core/components/Sort.js +398 -0
  304. package/src/Core/components/Sources.js +108 -0
  305. package/src/Core/components/Split.js +205 -0
  306. package/src/Core/components/Spreadsheet.js +1507 -0
  307. package/src/Core/components/StyleDefinitions.js +111 -0
  308. package/src/Core/components/SubsetOfReals.js +348 -0
  309. package/src/Core/components/SubsetOfRealsInput.js +1474 -0
  310. package/src/Core/components/Substitute.js +496 -0
  311. package/src/Core/components/SummaryStatistics.js +652 -0
  312. package/src/Core/components/Table.js +145 -0
  313. package/src/Core/components/Tabular.js +384 -0
  314. package/src/Core/components/Template.js +360 -0
  315. package/src/Core/components/Text.js +341 -0
  316. package/src/Core/components/TextInput.js +566 -0
  317. package/src/Core/components/TextList.js +442 -0
  318. package/src/Core/components/TextListFromString.js +137 -0
  319. package/src/Core/components/TextOperatorsOfMath.js +21 -0
  320. package/src/Core/components/Triangle.js +280 -0
  321. package/src/Core/components/TriggerSet.js +189 -0
  322. package/src/Core/components/TupleList.js +43 -0
  323. package/src/Core/components/UpdateValue.js +435 -0
  324. package/src/Core/components/VariantControl.js +36 -0
  325. package/src/Core/components/Vector.js +2478 -0
  326. package/src/Core/components/Verbatim.js +125 -0
  327. package/src/Core/components/Video.js +673 -0
  328. package/src/Core/components/When.js +198 -0
  329. package/src/Core/components/abstract/AngleListComponent.js +140 -0
  330. package/src/Core/components/abstract/BaseComponent.js +1496 -0
  331. package/src/Core/components/abstract/BlockComponent.js +5 -0
  332. package/src/Core/components/abstract/BooleanBaseOperator.js +88 -0
  333. package/src/Core/components/abstract/BooleanBaseOperatorOfMath.js +100 -0
  334. package/src/Core/components/abstract/BooleanBaseOperatorOneInput.js +44 -0
  335. package/src/Core/components/abstract/ComponentSize.js +789 -0
  336. package/src/Core/components/abstract/ComponentWithSelectableType.js +537 -0
  337. package/src/Core/components/abstract/CompositeComponent.js +142 -0
  338. package/src/Core/components/abstract/ConstraintComponent.js +19 -0
  339. package/src/Core/components/abstract/FunctionBaseOperator.js +680 -0
  340. package/src/Core/components/abstract/GraphicalComponent.js +56 -0
  341. package/src/Core/components/abstract/InlineComponent.js +5 -0
  342. package/src/Core/components/abstract/InlineRenderInlineChildren.js +63 -0
  343. package/src/Core/components/abstract/Input.js +192 -0
  344. package/src/Core/components/abstract/IntervalListComponent.js +218 -0
  345. package/src/Core/components/abstract/LineListComponent.js +114 -0
  346. package/src/Core/components/abstract/MathBaseOperator.js +631 -0
  347. package/src/Core/components/abstract/MathBaseOperatorOneInput.js +112 -0
  348. package/src/Core/components/abstract/PointListComponent.js +238 -0
  349. package/src/Core/components/abstract/SectioningComponent.js +1262 -0
  350. package/src/Core/components/abstract/SingleCharacterInline.js +23 -0
  351. package/src/Core/components/abstract/TextBaseOperatorOfMath.js +47 -0
  352. package/src/Core/components/abstract/TextOrInline.js +66 -0
  353. package/src/Core/components/abstract/VariableName.js +31 -0
  354. package/src/Core/components/abstract/VariableNameList.js +83 -0
  355. package/src/Core/components/abstract/VectorListComponent.js +235 -0
  356. package/src/Core/components/chemistry/Atom.js +910 -0
  357. package/src/Core/components/chemistry/ElectronConfiguration.js +36 -0
  358. package/src/Core/components/chemistry/Ion.js +684 -0
  359. package/src/Core/components/chemistry/IonicCompound.js +189 -0
  360. package/src/Core/components/chemistry/OrbitalDiagram.js +175 -0
  361. package/src/Core/components/chemistry/OrbitalDiagramInput.js +753 -0
  362. package/src/Core/components/chemistry/index.js +6 -0
  363. package/src/Core/components/commonsugar/breakstrings.js +627 -0
  364. package/src/Core/components/commonsugar/lists.js +177 -0
  365. package/src/Core/components/dynamicalSystems/CobwebPolyline.js +913 -0
  366. package/src/Core/components/dynamicalSystems/EquilibriumCurve.js +95 -0
  367. package/src/Core/components/dynamicalSystems/EquilibriumLine.js +93 -0
  368. package/src/Core/components/dynamicalSystems/EquilibriumPoint.js +93 -0
  369. package/src/Core/components/dynamicalSystems/ODESystem.js +943 -0
  370. package/src/Core/components/dynamicalSystems/index.js +5 -0
  371. package/src/Core/components/linearAlgebra/EigenDecomposition.js +294 -0
  372. package/src/Core/utils/array.js +30 -0
  373. package/src/Core/utils/booleanLogic.js +965 -0
  374. package/src/Core/utils/checkEquality.js +818 -0
  375. package/src/Core/utils/cid.js +29 -0
  376. package/src/Core/utils/componentInfoObjects.js +100 -0
  377. package/src/Core/utils/constraints.js +23 -0
  378. package/src/Core/utils/copy.js +572 -0
  379. package/src/Core/utils/deepFunctions.js +173 -0
  380. package/src/Core/utils/descendants.js +252 -0
  381. package/src/Core/utils/enumeration.js +234 -0
  382. package/src/Core/utils/feedback.js +84 -0
  383. package/src/Core/utils/function.js +1343 -0
  384. package/src/Core/utils/graphical.js +196 -0
  385. package/src/Core/utils/label.js +396 -0
  386. package/src/Core/utils/math.js +1056 -0
  387. package/src/Core/utils/naming.js +45 -0
  388. package/src/Core/utils/periodicSetEquality.js +403 -0
  389. package/src/Core/utils/randomNumbers.js +70 -0
  390. package/src/Core/utils/retrieveMedia.js +98 -0
  391. package/src/Core/utils/retrieveTextFile.js +140 -0
  392. package/src/Core/utils/returnAllPossibleVariants.js +73 -0
  393. package/src/Core/utils/rounding.js +316 -0
  394. package/src/Core/utils/sequence.js +754 -0
  395. package/src/Core/utils/serializedStateProcessing.js +4049 -0
  396. package/src/Core/utils/size.js +22 -0
  397. package/src/Core/utils/stateVariables.js +138 -0
  398. package/src/Core/utils/style.js +535 -0
  399. package/src/Core/utils/subset-of-reals.js +796 -0
  400. package/src/Core/utils/table.js +41 -0
  401. package/src/Core/utils/text.js +16 -0
  402. package/src/Core/utils/triggering.js +167 -0
  403. package/src/Core/utils/variants.js +477 -0
  404. package/src/DoenetML.css +308 -0
  405. package/src/DoenetML.jsx +201 -0
  406. package/src/Parser/doenet.grammar +90 -0
  407. package/src/Parser/doenet.js +33 -0
  408. package/src/Parser/doenet.terms.js +20 -0
  409. package/src/Parser/parser.js +266 -0
  410. package/src/Parser/tokens.js +129 -0
  411. package/src/Tools/CodeMirror.jsx +440 -0
  412. package/src/Tools/DarkmodeController.jsx +21 -0
  413. package/src/Tools/Footers/MathInputSelector.jsx +34 -0
  414. package/src/Tools/Footers/VirtualKeyboard.jsx +751 -0
  415. package/src/Tools/cypressTest/CypressTest.jsx +341 -0
  416. package/src/Tools/cypressTest/index.html +102 -0
  417. package/src/Tools/cypressTest/index.jsx +40 -0
  418. package/src/Viewer/ActivityViewer.jsx +1461 -0
  419. package/src/Viewer/PageViewer.jsx +1329 -0
  420. package/src/Viewer/renderers/alert.jsx +17 -0
  421. package/src/Viewer/renderers/angle.jsx +209 -0
  422. package/src/Viewer/renderers/answer.jsx +206 -0
  423. package/src/Viewer/renderers/asList.jsx +25 -0
  424. package/src/Viewer/renderers/blockQuote.jsx +41 -0
  425. package/src/Viewer/renderers/boolean.jsx +17 -0
  426. package/src/Viewer/renderers/booleanInput.css +105 -0
  427. package/src/Viewer/renderers/booleanInput.jsx +636 -0
  428. package/src/Viewer/renderers/button.jsx +369 -0
  429. package/src/Viewer/renderers/c.jsx +17 -0
  430. package/src/Viewer/renderers/callAction.jsx +18 -0
  431. package/src/Viewer/renderers/cell.jsx +59 -0
  432. package/src/Viewer/renderers/chart.jsx +83 -0
  433. package/src/Viewer/renderers/choiceInput.css +223 -0
  434. package/src/Viewer/renderers/choiceInput.jsx +535 -0
  435. package/src/Viewer/renderers/circle.jsx +990 -0
  436. package/src/Viewer/renderers/cobwebPolyline.jsx +442 -0
  437. package/src/Viewer/renderers/codeEditor.jsx +248 -0
  438. package/src/Viewer/renderers/codeViewer.jsx +105 -0
  439. package/src/Viewer/renderers/containerBlock.jsx +41 -0
  440. package/src/Viewer/renderers/containerInline.jsx +17 -0
  441. package/src/Viewer/renderers/contentBrowser.jsx +159 -0
  442. package/src/Viewer/renderers/contentPicker.jsx +160 -0
  443. package/src/Viewer/renderers/curve.jsx +1072 -0
  444. package/src/Viewer/renderers/ellipsis.jsx +17 -0
  445. package/src/Viewer/renderers/em.jsx +17 -0
  446. package/src/Viewer/renderers/embed.jsx +110 -0
  447. package/src/Viewer/renderers/feedback.jsx +74 -0
  448. package/src/Viewer/renderers/figure.jsx +131 -0
  449. package/src/Viewer/renderers/footnote.jsx +52 -0
  450. package/src/Viewer/renderers/graph.jsx +925 -0
  451. package/src/Viewer/renderers/hint.jsx +142 -0
  452. package/src/Viewer/renderers/image.jsx +581 -0
  453. package/src/Viewer/renderers/jsxgraph-distrib/jsxgraphcore.mjs +2 -0
  454. package/src/Viewer/renderers/jsxgraph-distrib/jsxgraphcore.mjs.map +1 -0
  455. package/src/Viewer/renderers/label.jsx +470 -0
  456. package/src/Viewer/renderers/legend.jsx +306 -0
  457. package/src/Viewer/renderers/line.jsx +511 -0
  458. package/src/Viewer/renderers/lineSegment.jsx +754 -0
  459. package/src/Viewer/renderers/list.jsx +111 -0
  460. package/src/Viewer/renderers/lq.jsx +12 -0
  461. package/src/Viewer/renderers/lsq.jsx +12 -0
  462. package/src/Viewer/renderers/math.jsx +582 -0
  463. package/src/Viewer/renderers/mathInput.css +10 -0
  464. package/src/Viewer/renderers/mathInput.jsx +425 -0
  465. package/src/Viewer/renderers/mathInputog.jsx +534 -0
  466. package/src/Viewer/renderers/mathList.jsx +39 -0
  467. package/src/Viewer/renderers/matrixInput.jsx +317 -0
  468. package/src/Viewer/renderers/mdash.jsx +12 -0
  469. package/src/Viewer/renderers/nbsp.jsx +12 -0
  470. package/src/Viewer/renderers/ndash.jsx +12 -0
  471. package/src/Viewer/renderers/number.jsx +454 -0
  472. package/src/Viewer/renderers/numberList.jsx +35 -0
  473. package/src/Viewer/renderers/orbitalDiagram.jsx +247 -0
  474. package/src/Viewer/renderers/orbitalDiagramInput.jsx +450 -0
  475. package/src/Viewer/renderers/p.jsx +38 -0
  476. package/src/Viewer/renderers/paginatorControls.jsx +41 -0
  477. package/src/Viewer/renderers/pegboard.jsx +239 -0
  478. package/src/Viewer/renderers/point.jsx +649 -0
  479. package/src/Viewer/renderers/polygon.jsx +612 -0
  480. package/src/Viewer/renderers/polyline.jsx +608 -0
  481. package/src/Viewer/renderers/pre.jsx +34 -0
  482. package/src/Viewer/renderers/q.jsx +17 -0
  483. package/src/Viewer/renderers/ray.jsx +410 -0
  484. package/src/Viewer/renderers/ref.jsx +149 -0
  485. package/src/Viewer/renderers/regionBetweenCurveXAxis.jsx +182 -0
  486. package/src/Viewer/renderers/renderDoenetML.jsx +56 -0
  487. package/src/Viewer/renderers/row.jsx +31 -0
  488. package/src/Viewer/renderers/rq.jsx +12 -0
  489. package/src/Viewer/renderers/rsq.jsx +12 -0
  490. package/src/Viewer/renderers/section.jsx +427 -0
  491. package/src/Viewer/renderers/sideBySide.jsx +80 -0
  492. package/src/Viewer/renderers/slider.jsx +800 -0
  493. package/src/Viewer/renderers/solution.jsx +134 -0
  494. package/src/Viewer/renderers/spreadsheet.jsx +83 -0
  495. package/src/Viewer/renderers/sq.jsx +17 -0
  496. package/src/Viewer/renderers/styles/global.css +14 -0
  497. package/src/Viewer/renderers/subsetOfRealsInput.jsx +392 -0
  498. package/src/Viewer/renderers/summaryStatistics.jsx +83 -0
  499. package/src/Viewer/renderers/table.jsx +78 -0
  500. package/src/Viewer/renderers/tabular.jsx +58 -0
  501. package/src/Viewer/renderers/tag.jsx +26 -0
  502. package/src/Viewer/renderers/text.jsx +439 -0
  503. package/src/Viewer/renderers/textInput.jsx +774 -0
  504. package/src/Viewer/renderers/textList.jsx +30 -0
  505. package/src/Viewer/renderers/triggerSet.jsx +52 -0
  506. package/src/Viewer/renderers/updateValue.jsx +30 -0
  507. package/src/Viewer/renderers/utils/css.js +13 -0
  508. package/src/Viewer/renderers/utils/graph.js +159 -0
  509. package/src/Viewer/renderers/utils/offGraphIndicators.js +91 -0
  510. package/src/Viewer/renderers/vector.jsx +678 -0
  511. package/src/Viewer/renderers/video.jsx +494 -0
  512. package/src/Viewer/useDoenetRenderer.jsx +128 -0
  513. package/src/main.jsx +16 -0
  514. package/src/media/fonts/files/open-sans-v18-latin-700.woff +0 -0
  515. package/src/media/fonts/files/open-sans-v18-latin-700.woff2 +0 -0
  516. package/src/media/fonts/files/open-sans-v18-latin-700italic.woff +0 -0
  517. package/src/media/fonts/files/open-sans-v18-latin-700italic.woff2 +0 -0
  518. package/src/media/fonts/files/open-sans-v18-latin-italic.woff +0 -0
  519. package/src/media/fonts/files/open-sans-v18-latin-italic.woff2 +0 -0
  520. package/src/media/fonts/files/open-sans-v18-latin-light-italic.woff +0 -0
  521. package/src/media/fonts/files/open-sans-v18-latin-light-italic.woff2 +0 -0
  522. package/src/media/fonts/files/open-sans-v18-latin-light.woff +0 -0
  523. package/src/media/fonts/files/open-sans-v18-latin-light.woff2 +0 -0
  524. package/src/media/fonts/files/open-sans-v18-latin-regular.woff +0 -0
  525. package/src/media/fonts/files/open-sans-v18-latin-regular.woff2 +0 -0
  526. package/src/test/testCode.doenet +26 -0
  527. package/src/test/testViewer.jsx +158 -0
  528. package/src/uiComponents/ActionButton.jsx +157 -0
  529. package/src/uiComponents/ActionButtonGroup.jsx +93 -0
  530. package/src/uiComponents/Button.jsx +160 -0
  531. package/src/uiComponents/ButtonGroup.jsx +56 -0
  532. package/src/uiComponents/ToggleButton.jsx +194 -0
  533. package/src/uiComponents/ToggleButtonGroup.jsx +77 -0
  534. package/src/utils/activityUtils.js +713 -0
  535. package/src/utils/array.js +17 -0
  536. package/src/utils/cid.js +34 -0
  537. package/src/utils/componentInfoObjects.js +89 -0
  538. package/src/utils/deepFunctions.js +165 -0
  539. package/src/utils/enumeration.js +226 -0
  540. package/src/utils/math.js +624 -0
  541. package/src/utils/naming.js +44 -0
  542. package/src/utils/retrieveTextFile.js +156 -0
  543. package/src/utils/returnAllPossibleVariants.js +81 -0
  544. package/src/utils/sequence.js +715 -0
  545. package/src/utils/serialize.js +29 -0
  546. package/src/utils/serializedStateProcessing.js +2587 -0
  547. package/src/utils/subset-of-reals.js +783 -0
  548. package/src/utils/url.js +19 -0
  549. package/vite.config.js +14 -0
@@ -0,0 +1,2491 @@
1
+ import { createFunctionFromDefinition } from "../../../../src/Core/utils/function";
2
+ import { widthsBySize } from "../../../../src/Core/utils/size";
3
+ import { cesc, cesc2 } from "../../../../src/utils/url";
4
+
5
+ describe("Graph Tag Tests", function () {
6
+ beforeEach(() => {
7
+ cy.clearIndexedDB();
8
+ cy.visit("/src/Tools/cypressTest/");
9
+ });
10
+
11
+ it.skip("string sugared to curve in graph", () => {
12
+ cy.window().then(async (win) => {
13
+ win.postMessage(
14
+ {
15
+ doenetML: `
16
+ <text>a</text>
17
+ <graph>x^2</graph>
18
+ `,
19
+ },
20
+ "*",
21
+ );
22
+ });
23
+
24
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
25
+
26
+ cy.window().then(async (win) => {
27
+ let stateVariables = await win.returnAllStateVariables1();
28
+ let curve = stateVariables["/_graph1"].activeChildren[0];
29
+ expect(curve.stateValues.flipFunction).eq(false);
30
+ expect(curve.stateValues.fs[0](-2)).eq(4);
31
+ expect(curve.stateValues.fs[0](3)).eq(9);
32
+ });
33
+ });
34
+
35
+ it.skip("y = function string sugared to curve in graph", () => {
36
+ cy.window().then(async (win) => {
37
+ win.postMessage(
38
+ {
39
+ doenetML: `
40
+ <text>a</text>
41
+ <graph>y=x^2</graph>
42
+ `,
43
+ },
44
+ "*",
45
+ );
46
+ });
47
+
48
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
49
+
50
+ cy.window().then(async (win) => {
51
+ let stateVariables = await win.returnAllStateVariables1();
52
+ let curve = stateVariables["/_graph1"].activeChildren[0];
53
+ let functioncurve = curve.activeChildren[0];
54
+ expect(curve.stateValues.variables[0].tree).eq("x");
55
+ expect(curve.stateValues.variables[1].tree).eq("y");
56
+ expect(functioncurve.stateValues.variables[0].tree).eq("x");
57
+ expect(functioncurve.stateValues.variables[1].tree).eq("y");
58
+ expect(functioncurve.stateValues.flipFunction).eq(false);
59
+ expect(functioncurve.stateValues.f(-2)).eq(4);
60
+ expect(functioncurve.stateValues.f(3)).eq(9);
61
+ });
62
+ });
63
+
64
+ it.skip("inverse function string sugared to curve in graph", () => {
65
+ cy.window().then(async (win) => {
66
+ win.postMessage(
67
+ {
68
+ doenetML: `
69
+ <text>a</text>
70
+ <graph>y^2=x</graph>
71
+ `,
72
+ },
73
+ "*",
74
+ );
75
+ });
76
+
77
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
78
+
79
+ cy.window().then(async (win) => {
80
+ let stateVariables = await win.returnAllStateVariables1();
81
+ let curve = stateVariables["/_graph1"].activeChildren[0];
82
+ let functioncurve = curve.activeChildren[0];
83
+ expect(curve.stateValues.variables[0].tree).eq("x");
84
+ expect(curve.stateValues.variables[1].tree).eq("y");
85
+ expect(functioncurve.stateValues.variables[0].tree).eq("x");
86
+ expect(functioncurve.stateValues.variables[1].tree).eq("y");
87
+ expect(functioncurve.stateValues.flipFunction).eq(true);
88
+ expect(functioncurve.stateValues.f(-2)).eq(4);
89
+ expect(functioncurve.stateValues.f(3)).eq(9);
90
+ });
91
+ });
92
+
93
+ it("functions sugared to curves in graph", () => {
94
+ cy.window().then(async (win) => {
95
+ win.postMessage(
96
+ {
97
+ doenetML: `
98
+ <text>a</text>
99
+ <graph>
100
+ <function>x^2</function>
101
+ <function variables="t" stylenumber="2"><label>g</label>t^3</function>
102
+ </graph>
103
+ `,
104
+ },
105
+ "*",
106
+ );
107
+ });
108
+
109
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
110
+
111
+ cy.window().then(async (win) => {
112
+ let stateVariables = await win.returnAllStateVariables1();
113
+ let curve1Name =
114
+ stateVariables["/_graph1"].activeChildren[0].componentName;
115
+ let curve2Name =
116
+ stateVariables["/_graph1"].activeChildren[1].componentName;
117
+
118
+ let f1 = createFunctionFromDefinition(
119
+ stateVariables[curve1Name].stateValues.fDefinitions[0],
120
+ );
121
+ let f2 = createFunctionFromDefinition(
122
+ stateVariables[curve2Name].stateValues.fDefinitions[0],
123
+ );
124
+ expect(f1(-2)).eq(4);
125
+ expect(f1(3)).eq(9);
126
+ expect(f2(-2)).eq(-8);
127
+ expect(f2(3)).eq(27);
128
+ expect(stateVariables[curve1Name].stateValues.label).eq("");
129
+ expect(stateVariables[curve2Name].stateValues.label).eq("g");
130
+ expect(stateVariables[curve1Name].stateValues.styleNumber).eq(1);
131
+ expect(stateVariables[curve2Name].stateValues.styleNumber).eq(2);
132
+ });
133
+ });
134
+
135
+ it("changing bounding box", () => {
136
+ cy.window().then(async (win) => {
137
+ win.postMessage(
138
+ {
139
+ doenetML: `
140
+ <text>a</text>
141
+ <graph><point>(0,0)</point>
142
+ </graph>
143
+
144
+ <p>xmin: <copy prop="xmin" target="_graph1" assignNames="xmin" /></p>
145
+ <p>xmax: <copy prop="xmax" target="_graph1" assignNames="xmax" /></p>
146
+ <p>ymin: <copy prop="ymin" target="_graph1" assignNames="ymin" /></p>
147
+ <p>ymax: <copy prop="ymax" target="_graph1" assignNames="ymax" /></p>
148
+
149
+ <p>Change xmin: <mathinput name="xminInput" bindValueTo="$_graph1.xmin" /></p>
150
+ <p>Change xmax: <mathinput name="xmaxInput" bindValueTo="$_graph1.xmax" /></p>
151
+ <p>Change ymin: <mathinput name="yminInput" bindValueTo="$_graph1.ymin" /></p>
152
+ <p>Change ymax: <mathinput name="ymaxInput" bindValueTo="$_graph1.ymax" /></p>
153
+
154
+ `,
155
+ },
156
+ "*",
157
+ );
158
+ });
159
+
160
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
161
+
162
+ function checkLimits(xmin, xmax, ymin, ymax) {
163
+ cy.get(cesc("#\\/xmin")).should("have.text", String(xmin));
164
+ cy.get(cesc("#\\/xmax")).should("have.text", String(xmax));
165
+ cy.get(cesc("#\\/ymin")).should("have.text", String(ymin));
166
+ cy.get(cesc("#\\/ymax")).should("have.text", String(ymax));
167
+
168
+ cy.window().then(async (win) => {
169
+ let stateVariables = await win.returnAllStateVariables1();
170
+ expect(stateVariables["/_graph1"].stateValues.xmin).eq(xmin);
171
+ expect(stateVariables["/_graph1"].stateValues.xmax).eq(xmax);
172
+ expect(stateVariables["/_graph1"].stateValues.ymin).eq(ymin);
173
+ expect(stateVariables["/_graph1"].stateValues.ymax).eq(ymax);
174
+ });
175
+ }
176
+
177
+ let xmin = -10,
178
+ xmax = 10,
179
+ ymin = -10,
180
+ ymax = 10;
181
+
182
+ checkLimits(xmin, xmax, ymin, ymax);
183
+
184
+ cy.get(cesc("#\\/_graph1_navigationbar") + " > :nth-child(6)")
185
+ .click()
186
+ .then((_) => {
187
+ let increment = 0.1 * (ymax - ymin);
188
+ ymin += increment;
189
+ ymax += increment;
190
+ checkLimits(xmin, xmax, ymin, ymax);
191
+ });
192
+
193
+ cy.get(cesc("#\\/_graph1_navigationbar") + " > :nth-child(6)")
194
+ .click()
195
+ .then((_) => {
196
+ let increment = 0.1 * (ymax - ymin);
197
+ ymin += increment;
198
+ ymax += increment;
199
+ checkLimits(xmin, xmax, ymin, ymax);
200
+ });
201
+
202
+ cy.get(cesc("#\\/_graph1_navigationbar") + " > :nth-child(5)")
203
+ .click()
204
+ .then((_) => {
205
+ let increment = 0.1 * (ymax - ymin);
206
+ ymin -= increment;
207
+ ymax -= increment;
208
+ checkLimits(xmin, xmax, ymin, ymax);
209
+ });
210
+
211
+ cy.get(cesc("#\\/_graph1_navigationbar") + " > :nth-child(4)")
212
+ .click()
213
+ .then((_) => {
214
+ let increment = 0.1 * (xmax - xmin);
215
+ xmin -= increment;
216
+ xmax -= increment;
217
+ checkLimits(xmin, xmax, ymin, ymax);
218
+ });
219
+
220
+ cy.get(cesc("#\\/_graph1_navigationbar") + " > :nth-child(7)")
221
+ .click()
222
+ .then((_) => {
223
+ let increment = 0.1 * (xmax - xmin);
224
+ xmin += increment;
225
+ xmax += increment;
226
+ checkLimits(xmin, xmax, ymin, ymax);
227
+ });
228
+
229
+ cy.get(cesc("#\\/_graph1_navigationbar") + " > :nth-child(7)")
230
+ .click()
231
+ .then((_) => {
232
+ let increment = 0.1 * (xmax - xmin);
233
+ xmin += increment;
234
+ xmax += increment;
235
+ checkLimits(xmin, xmax, ymin, ymax);
236
+ });
237
+
238
+ cy.get(cesc("#\\/_graph1_navigationbar") + " > :nth-child(3)")
239
+ .click()
240
+ .then((_) => {
241
+ let meanx = (xmax + xmin) / 2;
242
+ xmin = meanx + 0.8 * (xmin - meanx);
243
+ xmax = meanx + 0.8 * (xmax - meanx);
244
+ let meany = (ymax + ymin) / 2;
245
+ ymin = meany + 0.8 * (ymin - meany);
246
+ ymax = meany + 0.8 * (ymax - meany);
247
+ checkLimits(xmin, xmax, ymin, ymax);
248
+ });
249
+
250
+ cy.get(cesc("#\\/_graph1_navigationbar") + " > :nth-child(3)")
251
+ .click()
252
+ .then((_) => {
253
+ let meanx = (xmax + xmin) / 2;
254
+ xmin = meanx + 0.8 * (xmin - meanx);
255
+ xmax = meanx + 0.8 * (xmax - meanx);
256
+ let meany = (ymax + ymin) / 2;
257
+ ymin = meany + 0.8 * (ymin - meany);
258
+ ymax = meany + 0.8 * (ymax - meany);
259
+ checkLimits(xmin, xmax, ymin, ymax);
260
+ });
261
+
262
+ cy.get(cesc("#\\/_graph1_navigationbar") + " > :nth-child(1)")
263
+ .click()
264
+ .then((_) => {
265
+ let meanx = (xmax + xmin) / 2;
266
+ xmin = meanx + (xmin - meanx) / 0.8;
267
+ xmax = meanx + (xmax - meanx) / 0.8;
268
+ let meany = (ymax + ymin) / 2;
269
+ ymin = meany + (ymin - meany) / 0.8;
270
+ ymax = meany + (ymax - meany) / 0.8;
271
+ checkLimits(xmin, xmax, ymin, ymax);
272
+ });
273
+
274
+ cy.get(cesc("#\\/xminInput") + " textarea")
275
+ .type(`{end}{backspace}{backspace}-8{enter}`, { force: true })
276
+ .then((_) => {
277
+ xmin = -8;
278
+ checkLimits(xmin, xmax, ymin, ymax);
279
+ });
280
+
281
+ cy.get(cesc("#\\/xmaxInput") + " textarea")
282
+ .type(`{end}{backspace}{backspace}12{enter}`, { force: true })
283
+ .then((_) => {
284
+ xmax = 12;
285
+ checkLimits(xmin, xmax, ymin, ymax);
286
+ });
287
+
288
+ cy.get(cesc("#\\/yminInput") + " textarea")
289
+ .type(`{end}{backspace}{backspace}-4{enter}`, { force: true })
290
+ .then((_) => {
291
+ ymin = -4;
292
+ checkLimits(xmin, xmax, ymin, ymax);
293
+ });
294
+
295
+ cy.get(cesc("#\\/ymaxInput") + " textarea")
296
+ .type(`{end}{backspace}{backspace}16{enter}`, { force: true })
297
+ .then((_) => {
298
+ ymax = 16;
299
+ checkLimits(xmin, xmax, ymin, ymax);
300
+ });
301
+
302
+ cy.get(cesc("#\\/_graph1_navigationbar") + " > :nth-child(5)")
303
+ .click()
304
+ .then((_) => {
305
+ let increment = 0.1 * (ymax - ymin);
306
+ ymin -= increment;
307
+ ymax -= increment;
308
+ checkLimits(xmin, xmax, ymin, ymax);
309
+ });
310
+
311
+ cy.get(cesc("#\\/_graph1_navigationbar") + " > :nth-child(4)")
312
+ .click()
313
+ .then((_) => {
314
+ let increment = 0.1 * (xmax - xmin);
315
+ xmin -= increment;
316
+ xmax -= increment;
317
+ checkLimits(xmin, xmax, ymin, ymax);
318
+ });
319
+ });
320
+
321
+ it("labels and positioning", () => {
322
+ cy.window().then(async (win) => {
323
+ win.postMessage(
324
+ {
325
+ doenetML: `
326
+ <text>a</text>
327
+
328
+ <graph name="g" xlabelPosition="$xlabelpos" ylabelPosition="$ylabelpos" ylabelAlignment="$ylabelalign">
329
+ <xlabel>$xlabel</xlabel><ylabel>$ylabel</ylabel>
330
+ </graph>
331
+
332
+ <tabular>
333
+ <row>
334
+ <cell>xlabel: <textinput name="xlabel" prefill="x" /></cell>
335
+ <cell>position:
336
+ <choiceinput inline preselectChoice="2" name="xlabelpos">
337
+ <choice>left</choice>
338
+ <choice>right</choice>
339
+ </choiceinput></cell>
340
+ </row>
341
+ <row>
342
+ <cell>ylabel: <textinput name="ylabel" prefill="y" /></cell>
343
+ <cell>position:
344
+ <choiceinput inline preselectChoice="1" name="ylabelpos">
345
+ <choice>top</choice>
346
+ <choice>bottom</choice>
347
+ </choiceinput>
348
+ </cell>
349
+ <cell>alignment:
350
+ <choiceinput inline preselectChoice="1" name="ylabelalign">
351
+ <choice>left</choice>
352
+ <choice>right</choice>
353
+ </choiceinput>
354
+ </cell>
355
+ </row>
356
+ </tabular>
357
+ `,
358
+ },
359
+ "*",
360
+ );
361
+ });
362
+
363
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
364
+
365
+ // not sure what to test as don't know how to check renderer...
366
+
367
+ cy.window().then(async (win) => {
368
+ let stateVariables = await win.returnAllStateVariables1();
369
+ expect(stateVariables["/g"].stateValues.xlabel).eq("x");
370
+ expect(stateVariables["/g"].stateValues.xlabelPosition).eq("right");
371
+ expect(stateVariables["/g"].stateValues.ylabel).eq("y");
372
+ expect(stateVariables["/g"].stateValues.ylabelPosition).eq("top");
373
+ expect(stateVariables["/g"].stateValues.ylabelAlignment).eq("left");
374
+ });
375
+
376
+ cy.get(cesc("#\\/xlabel_input")).clear().type("hello{enter}");
377
+ cy.get(cesc("#\\/ylabel_input")).clear().type("bye{enter}");
378
+ cy.get(cesc("#\\/xlabelpos")).select("left");
379
+ cy.get(cesc("#\\/ylabelpos")).select("bottom");
380
+ cy.get(cesc("#\\/ylabelalign")).select("right");
381
+
382
+ cy.window().then(async (win) => {
383
+ let stateVariables = await win.returnAllStateVariables1();
384
+ expect(stateVariables["/g"].stateValues.xlabel).eq("hello");
385
+ expect(stateVariables["/g"].stateValues.xlabelPosition).eq("left");
386
+ expect(stateVariables["/g"].stateValues.ylabel).eq("bye");
387
+ expect(stateVariables["/g"].stateValues.ylabelPosition).eq("bottom");
388
+ expect(stateVariables["/g"].stateValues.ylabelAlignment).eq("right");
389
+ });
390
+ });
391
+
392
+ it("change essential xlable and ylabel", () => {
393
+ cy.window().then(async (win) => {
394
+ win.postMessage(
395
+ {
396
+ doenetML: `
397
+ <graph name="g" />
398
+ <p><updateValue name="uvx" target="g.xlabel" type="text" newValue="s" ><label>Change x-label</label></updateValue></p>
399
+ <p><updateValue name="uvy" target="g.ylabel" type="text" newValue="t" ><label>Change y-label</label></updateValue></p>
400
+
401
+ <p name="pxlabel">x-label: $g.xlabel</p>
402
+ <p name="pylabel">y-label: $g.ylabel</p>
403
+ `,
404
+ },
405
+ "*",
406
+ );
407
+ });
408
+
409
+ cy.get(cesc("#\\/pxlabel")).should("have.text", "x-label: ");
410
+ cy.get(cesc("#\\/pylabel")).should("have.text", "y-label: ");
411
+
412
+ cy.window().then(async (win) => {
413
+ let stateVariables = await win.returnAllStateVariables1();
414
+ expect(stateVariables["/g"].stateValues.xlabel).eq("");
415
+ expect(stateVariables["/g"].stateValues.ylabel).eq("");
416
+ });
417
+
418
+ cy.get(cesc("#\\/uvx")).click();
419
+ cy.get(cesc("#\\/pxlabel")).should("have.text", "x-label: s");
420
+ cy.get(cesc("#\\/uvy")).click();
421
+ cy.get(cesc("#\\/pylabel")).should("have.text", "y-label: t");
422
+
423
+ cy.window().then(async (win) => {
424
+ let stateVariables = await win.returnAllStateVariables1();
425
+ expect(stateVariables["/g"].stateValues.xlabel).eq("s");
426
+ expect(stateVariables["/g"].stateValues.ylabel).eq("t");
427
+ });
428
+ });
429
+
430
+ it("identical axis scales, with given aspect ratio", () => {
431
+ cy.window().then(async (win) => {
432
+ win.postMessage(
433
+ {
434
+ doenetML: `
435
+ <text>a</text>
436
+ <p>Aspect ratio: <mathinput name="aspectRatio" prefill="1" /></p>
437
+
438
+ <graph name="g" identicalAxisScales aspectRatio="$aspectRatio" />
439
+
440
+ <p>xmin: <copy prop="xmin" target="g" assignNames="xmin" /></p>
441
+ <p>xmax: <copy prop="xmax" target="g" assignNames="xmax" /></p>
442
+ <p>ymin: <copy prop="ymin" target="g" assignNames="ymin" /></p>
443
+ <p>ymax: <copy prop="ymax" target="g" assignNames="ymax" /></p>
444
+
445
+ `,
446
+ },
447
+ "*",
448
+ );
449
+ });
450
+
451
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
452
+
453
+ function checkLimits(xmin, xmax, ymin, ymax) {
454
+ cy.get(cesc("#\\/xmin")).should("have.text", String(xmin));
455
+ cy.get(cesc("#\\/xmax")).should("have.text", String(xmax));
456
+ cy.get(cesc("#\\/ymin")).should("have.text", String(ymin));
457
+ cy.get(cesc("#\\/ymax")).should("have.text", String(ymax));
458
+
459
+ cy.window().then(async (win) => {
460
+ let stateVariables = await win.returnAllStateVariables1();
461
+ expect(stateVariables["/g"].stateValues.xmin).eq(xmin);
462
+ expect(stateVariables["/g"].stateValues.xmax).eq(xmax);
463
+ expect(stateVariables["/g"].stateValues.ymin).eq(ymin);
464
+ expect(stateVariables["/g"].stateValues.ymax).eq(ymax);
465
+ });
466
+ }
467
+
468
+ let xmin = -10,
469
+ xmax = 10,
470
+ ymin = -10,
471
+ ymax = 10;
472
+
473
+ checkLimits(xmin, xmax, ymin, ymax);
474
+ cy.get(cesc("#\\/g"))
475
+ .invoke("css", "width")
476
+ .then((width) => parseInt(width))
477
+ .should("be.gte", 424)
478
+ .and("be.lte", 426);
479
+ cy.get(cesc("#\\/g"))
480
+ .invoke("css", "height")
481
+ .then((height) => parseInt(height))
482
+ .should("be.gte", 424)
483
+ .and("be.lte", 426);
484
+
485
+ cy.log("set aspect ratio to 2");
486
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
487
+ .type("{end}{backspace}2{enter}", { force: true })
488
+ .then(() => {
489
+ ymin = -5;
490
+ ymax = 5;
491
+ checkLimits(xmin, xmax, ymin, ymax);
492
+ cy.get(cesc("#\\/g"))
493
+ .invoke("css", "width")
494
+ .then((width) => parseInt(width))
495
+ .should("be.gte", 424)
496
+ .and("be.lte", 426);
497
+ cy.get(cesc("#\\/g"))
498
+ .invoke("css", "height")
499
+ .then((height) => parseInt(height))
500
+ .should("be.gte", 212)
501
+ .and("be.lte", 213);
502
+ });
503
+
504
+ cy.log("set aspect ratio to 1/2");
505
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
506
+ .type("{end}{backspace}1/2{enter}", { force: true })
507
+ .then(() => {
508
+ ymin = -20;
509
+ ymax = 20;
510
+ checkLimits(xmin, xmax, ymin, ymax);
511
+ cy.get(cesc("#\\/g"))
512
+ .invoke("css", "width")
513
+ .then((width) => parseInt(width))
514
+ .should("be.gte", 424)
515
+ .and("be.lte", 426);
516
+ cy.get(cesc("#\\/g"))
517
+ .invoke("css", "height")
518
+ .then((height) => parseInt(height))
519
+ .should("be.gte", 849)
520
+ .and("be.lte", 851);
521
+ });
522
+
523
+ cy.reload();
524
+
525
+ cy.log("xmin alone specified");
526
+ cy.window().then(async (win) => {
527
+ win.postMessage(
528
+ {
529
+ doenetML: `
530
+ <text>b</text>
531
+ <p>Aspect ratio: <mathinput name="aspectRatio" prefill="1" /></p>
532
+
533
+ <graph name="g" identicalAxisScales aspectRatio="$aspectRatio" xmin="-5" />
534
+
535
+ <p>xmin: <copy prop="xmin" target="g" assignNames="xmin" /></p>
536
+ <p>xmax: <copy prop="xmax" target="g" assignNames="xmax" /></p>
537
+ <p>ymin: <copy prop="ymin" target="g" assignNames="ymin" /></p>
538
+ <p>ymax: <copy prop="ymax" target="g" assignNames="ymax" /></p>
539
+
540
+ `,
541
+ },
542
+ "*",
543
+ );
544
+ });
545
+
546
+ //wait for page to load
547
+ cy.get(cesc("#\\/_text1"))
548
+ .should("have.text", "b")
549
+ .then(() => {
550
+ xmin = -5;
551
+ xmax = 15;
552
+ ymin = -10;
553
+ ymax = 10;
554
+ checkLimits(xmin, xmax, ymin, ymax);
555
+ cy.get(cesc("#\\/g"))
556
+ .invoke("css", "width")
557
+ .then((width) => parseInt(width))
558
+ .should("be.gte", 424)
559
+ .and("be.lte", 426);
560
+ cy.get(cesc("#\\/g"))
561
+ .invoke("css", "height")
562
+ .then((height) => parseInt(height))
563
+ .should("be.gte", 424)
564
+ .and("be.lte", 426);
565
+ });
566
+
567
+ cy.log("set aspect ratio to 2");
568
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
569
+ .type("{end}{backspace}2{enter}", { force: true })
570
+ .then(() => {
571
+ ymin = -5;
572
+ ymax = 5;
573
+ checkLimits(xmin, xmax, ymin, ymax);
574
+ cy.get(cesc("#\\/g"))
575
+ .invoke("css", "width")
576
+ .then((width) => parseInt(width))
577
+ .should("be.gte", 424)
578
+ .and("be.lte", 426);
579
+ cy.get(cesc("#\\/g"))
580
+ .invoke("css", "height")
581
+ .then((height) => parseInt(height))
582
+ .should("be.gte", 212)
583
+ .and("be.lte", 213);
584
+ });
585
+
586
+ cy.log("set aspect ratio to 1/2");
587
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
588
+ .type("{end}{backspace}1/2{enter}", { force: true })
589
+ .then(() => {
590
+ ymin = -20;
591
+ ymax = 20;
592
+ checkLimits(xmin, xmax, ymin, ymax);
593
+ cy.get(cesc("#\\/g"))
594
+ .invoke("css", "width")
595
+ .then((width) => parseInt(width))
596
+ .should("be.gte", 424)
597
+ .and("be.lte", 426);
598
+ cy.get(cesc("#\\/g"))
599
+ .invoke("css", "height")
600
+ .then((height) => parseInt(height))
601
+ .should("be.gte", 849)
602
+ .and("be.lte", 851);
603
+ });
604
+
605
+ cy.reload();
606
+
607
+ cy.log("xmax alone specified");
608
+ cy.window().then(async (win) => {
609
+ win.postMessage(
610
+ {
611
+ doenetML: `
612
+ <text>c</text>
613
+ <p>Aspect ratio: <mathinput name="aspectRatio" prefill="1" /></p>
614
+
615
+ <graph name="g" identicalAxisScales aspectRatio="$aspectRatio" xmax="5" />
616
+
617
+ <p>xmin: <copy prop="xmin" target="g" assignNames="xmin" /></p>
618
+ <p>xmax: <copy prop="xmax" target="g" assignNames="xmax" /></p>
619
+ <p>ymin: <copy prop="ymin" target="g" assignNames="ymin" /></p>
620
+ <p>ymax: <copy prop="ymax" target="g" assignNames="ymax" /></p>
621
+
622
+ `,
623
+ },
624
+ "*",
625
+ );
626
+ });
627
+
628
+ //wait for page to load
629
+ cy.get(cesc("#\\/_text1"))
630
+ .should("have.text", "c")
631
+ .then(() => {
632
+ xmin = -15;
633
+ xmax = 5;
634
+ ymin = -10;
635
+ ymax = 10;
636
+ checkLimits(xmin, xmax, ymin, ymax);
637
+ cy.get(cesc("#\\/g"))
638
+ .invoke("css", "width")
639
+ .then((width) => parseInt(width))
640
+ .should("be.gte", 424)
641
+ .and("be.lte", 426);
642
+ cy.get(cesc("#\\/g"))
643
+ .invoke("css", "height")
644
+ .then((height) => parseInt(height))
645
+ .should("be.gte", 424)
646
+ .and("be.lte", 426);
647
+ });
648
+
649
+ cy.log("set aspect ratio to 2");
650
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
651
+ .type("{end}{backspace}2{enter}", { force: true })
652
+ .then(() => {
653
+ ymin = -5;
654
+ ymax = 5;
655
+ checkLimits(xmin, xmax, ymin, ymax);
656
+ cy.get(cesc("#\\/g"))
657
+ .invoke("css", "width")
658
+ .then((width) => parseInt(width))
659
+ .should("be.gte", 424)
660
+ .and("be.lte", 426);
661
+ cy.get(cesc("#\\/g"))
662
+ .invoke("css", "height")
663
+ .then((height) => parseInt(height))
664
+ .should("be.gte", 212)
665
+ .and("be.lte", 213);
666
+ });
667
+
668
+ cy.log("set aspect ratio to 1/2");
669
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
670
+ .type("{end}{backspace}1/2{enter}", { force: true })
671
+ .then(() => {
672
+ ymin = -20;
673
+ ymax = 20;
674
+ checkLimits(xmin, xmax, ymin, ymax);
675
+ cy.get(cesc("#\\/g"))
676
+ .invoke("css", "width")
677
+ .then((width) => parseInt(width))
678
+ .should("be.gte", 424)
679
+ .and("be.lte", 426);
680
+ cy.get(cesc("#\\/g"))
681
+ .invoke("css", "height")
682
+ .then((height) => parseInt(height))
683
+ .should("be.gte", 849)
684
+ .and("be.lte", 851);
685
+ });
686
+
687
+ cy.reload();
688
+
689
+ cy.log("ymin alone specified");
690
+ cy.window().then(async (win) => {
691
+ win.postMessage(
692
+ {
693
+ doenetML: `
694
+ <text>d</text>
695
+ <p>Aspect ratio: <mathinput name="aspectRatio" prefill="1" /></p>
696
+
697
+ <graph name="g" identicalAxisScales aspectRatio="$aspectRatio" ymin="-5" />
698
+
699
+ <p>xmin: <copy prop="xmin" target="g" assignNames="xmin" /></p>
700
+ <p>xmax: <copy prop="xmax" target="g" assignNames="xmax" /></p>
701
+ <p>ymin: <copy prop="ymin" target="g" assignNames="ymin" /></p>
702
+ <p>ymax: <copy prop="ymax" target="g" assignNames="ymax" /></p>
703
+
704
+ `,
705
+ },
706
+ "*",
707
+ );
708
+ });
709
+
710
+ //wait for page to load
711
+ cy.get(cesc("#\\/_text1"))
712
+ .should("have.text", "d")
713
+ .then(() => {
714
+ xmin = -10;
715
+ xmax = 10;
716
+ ymin = -5;
717
+ ymax = 15;
718
+ checkLimits(xmin, xmax, ymin, ymax);
719
+ cy.get(cesc("#\\/g"))
720
+ .invoke("css", "width")
721
+ .then((width) => parseInt(width))
722
+ .should("be.gte", 424)
723
+ .and("be.lte", 426);
724
+ cy.get(cesc("#\\/g"))
725
+ .invoke("css", "height")
726
+ .then((height) => parseInt(height))
727
+ .should("be.gte", 424)
728
+ .and("be.lte", 426);
729
+ });
730
+
731
+ cy.log("set aspect ratio to 2");
732
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
733
+ .type("{end}{backspace}2{enter}", { force: true })
734
+ .then(() => {
735
+ ymax = 5;
736
+ checkLimits(xmin, xmax, ymin, ymax);
737
+ cy.get(cesc("#\\/g"))
738
+ .invoke("css", "width")
739
+ .then((width) => parseInt(width))
740
+ .should("be.gte", 424)
741
+ .and("be.lte", 426);
742
+ cy.get(cesc("#\\/g"))
743
+ .invoke("css", "height")
744
+ .then((height) => parseInt(height))
745
+ .should("be.gte", 212)
746
+ .and("be.lte", 213);
747
+ });
748
+
749
+ cy.log("set aspect ratio to 1/2");
750
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
751
+ .type("{end}{backspace}1/2{enter}", { force: true })
752
+ .then(() => {
753
+ ymax = 35;
754
+ checkLimits(xmin, xmax, ymin, ymax);
755
+ cy.get(cesc("#\\/g"))
756
+ .invoke("css", "width")
757
+ .then((width) => parseInt(width))
758
+ .should("be.gte", 424)
759
+ .and("be.lte", 426);
760
+ cy.get(cesc("#\\/g"))
761
+ .invoke("css", "height")
762
+ .then((height) => parseInt(height))
763
+ .should("be.gte", 849)
764
+ .and("be.lte", 851);
765
+ });
766
+
767
+ cy.reload();
768
+
769
+ cy.log("ymax alone specified");
770
+ cy.window().then(async (win) => {
771
+ win.postMessage(
772
+ {
773
+ doenetML: `
774
+ <text>e</text>
775
+ <p>Aspect ratio: <mathinput name="aspectRatio" prefill="1" /></p>
776
+
777
+ <graph name="g" identicalAxisScales aspectRatio="$aspectRatio" ymax="5" />
778
+
779
+ <p>xmin: <copy prop="xmin" target="g" assignNames="xmin" /></p>
780
+ <p>xmax: <copy prop="xmax" target="g" assignNames="xmax" /></p>
781
+ <p>ymin: <copy prop="ymin" target="g" assignNames="ymin" /></p>
782
+ <p>ymax: <copy prop="ymax" target="g" assignNames="ymax" /></p>
783
+
784
+ `,
785
+ },
786
+ "*",
787
+ );
788
+ });
789
+
790
+ //wait for page to load
791
+ cy.get(cesc("#\\/_text1"))
792
+ .should("have.text", "e")
793
+ .then(() => {
794
+ xmin = -10;
795
+ xmax = 10;
796
+ ymin = -15;
797
+ ymax = 5;
798
+ checkLimits(xmin, xmax, ymin, ymax);
799
+ cy.get(cesc("#\\/g"))
800
+ .invoke("css", "width")
801
+ .then((width) => parseInt(width))
802
+ .should("be.gte", 424)
803
+ .and("be.lte", 426);
804
+ cy.get(cesc("#\\/g"))
805
+ .invoke("css", "height")
806
+ .then((height) => parseInt(height))
807
+ .should("be.gte", 424)
808
+ .and("be.lte", 426);
809
+ });
810
+
811
+ cy.log("set aspect ratio to 2");
812
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
813
+ .type("{end}{backspace}2{enter}", { force: true })
814
+ .then(() => {
815
+ ymin = -5;
816
+ checkLimits(xmin, xmax, ymin, ymax);
817
+ cy.get(cesc("#\\/g"))
818
+ .invoke("css", "width")
819
+ .then((width) => parseInt(width))
820
+ .should("be.gte", 424)
821
+ .and("be.lte", 426);
822
+ cy.get(cesc("#\\/g"))
823
+ .invoke("css", "height")
824
+ .then((height) => parseInt(height))
825
+ .should("be.gte", 212)
826
+ .and("be.lte", 213);
827
+ });
828
+
829
+ cy.log("set aspect ratio to 1/2");
830
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
831
+ .type("{end}{backspace}1/2{enter}", { force: true })
832
+ .then(() => {
833
+ ymin = -35;
834
+ checkLimits(xmin, xmax, ymin, ymax);
835
+ cy.get(cesc("#\\/g"))
836
+ .invoke("css", "width")
837
+ .then((width) => parseInt(width))
838
+ .should("be.gte", 424)
839
+ .and("be.lte", 426);
840
+ cy.get(cesc("#\\/g"))
841
+ .invoke("css", "height")
842
+ .then((height) => parseInt(height))
843
+ .should("be.gte", 849)
844
+ .and("be.lte", 851);
845
+ });
846
+
847
+ cy.reload();
848
+
849
+ cy.log("xmin and xmax specified");
850
+ cy.window().then(async (win) => {
851
+ win.postMessage(
852
+ {
853
+ doenetML: `
854
+ <text>f</text>
855
+ <p>Aspect ratio: <mathinput name="aspectRatio" prefill="1" /></p>
856
+
857
+ <graph name="g" identicalAxisScales aspectRatio="$aspectRatio" xmin='-20' xmax="40" />
858
+
859
+ <p>xmin: <copy prop="xmin" target="g" assignNames="xmin" /></p>
860
+ <p>xmax: <copy prop="xmax" target="g" assignNames="xmax" /></p>
861
+ <p>ymin: <copy prop="ymin" target="g" assignNames="ymin" /></p>
862
+ <p>ymax: <copy prop="ymax" target="g" assignNames="ymax" /></p>
863
+
864
+ `,
865
+ },
866
+ "*",
867
+ );
868
+ });
869
+
870
+ //wait for page to load
871
+ cy.get(cesc("#\\/_text1"))
872
+ .should("have.text", "f")
873
+ .then(() => {
874
+ xmin = -20;
875
+ xmax = 40;
876
+ ymin = -30;
877
+ ymax = 30;
878
+ checkLimits(xmin, xmax, ymin, ymax);
879
+ cy.get(cesc("#\\/g"))
880
+ .invoke("css", "width")
881
+ .then((width) => parseInt(width))
882
+ .should("be.gte", 424)
883
+ .and("be.lte", 426);
884
+ cy.get(cesc("#\\/g"))
885
+ .invoke("css", "height")
886
+ .then((height) => parseInt(height))
887
+ .should("be.gte", 424)
888
+ .and("be.lte", 426);
889
+ });
890
+
891
+ cy.log("set aspect ratio to 2");
892
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
893
+ .type("{end}{backspace}2{enter}", { force: true })
894
+ .then(() => {
895
+ ymin = -15;
896
+ ymax = 15;
897
+ checkLimits(xmin, xmax, ymin, ymax);
898
+ cy.get(cesc("#\\/g"))
899
+ .invoke("css", "width")
900
+ .then((width) => parseInt(width))
901
+ .should("be.gte", 424)
902
+ .and("be.lte", 426);
903
+ cy.get(cesc("#\\/g"))
904
+ .invoke("css", "height")
905
+ .then((height) => parseInt(height))
906
+ .should("be.gte", 212)
907
+ .and("be.lte", 213);
908
+ });
909
+
910
+ cy.log("set aspect ratio to 1/2");
911
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
912
+ .type("{end}{backspace}1/2{enter}", { force: true })
913
+ .then(() => {
914
+ ymin = -60;
915
+ ymax = 60;
916
+ checkLimits(xmin, xmax, ymin, ymax);
917
+ cy.get(cesc("#\\/g"))
918
+ .invoke("css", "width")
919
+ .then((width) => parseInt(width))
920
+ .should("be.gte", 424)
921
+ .and("be.lte", 426);
922
+ cy.get(cesc("#\\/g"))
923
+ .invoke("css", "height")
924
+ .then((height) => parseInt(height))
925
+ .should("be.gte", 849)
926
+ .and("be.lte", 851);
927
+ });
928
+
929
+ cy.reload();
930
+
931
+ cy.log("ymin and ymax specified");
932
+ cy.window().then(async (win) => {
933
+ win.postMessage(
934
+ {
935
+ doenetML: `
936
+ <text>g</text>
937
+ <p>Aspect ratio: <mathinput name="aspectRatio" prefill="1" /></p>
938
+
939
+ <graph name="g" identicalAxisScales aspectRatio="$aspectRatio" ymin='-20' ymax="40" />
940
+
941
+ <p>xmin: <copy prop="xmin" target="g" assignNames="xmin" /></p>
942
+ <p>xmax: <copy prop="xmax" target="g" assignNames="xmax" /></p>
943
+ <p>ymin: <copy prop="ymin" target="g" assignNames="ymin" /></p>
944
+ <p>ymax: <copy prop="ymax" target="g" assignNames="ymax" /></p>
945
+
946
+ `,
947
+ },
948
+ "*",
949
+ );
950
+ });
951
+
952
+ //wait for page to load
953
+ cy.get(cesc("#\\/_text1"))
954
+ .should("have.text", "g")
955
+ .then(() => {
956
+ xmin = -30;
957
+ xmax = 30;
958
+ ymin = -20;
959
+ ymax = 40;
960
+ checkLimits(xmin, xmax, ymin, ymax);
961
+ cy.get(cesc("#\\/g"))
962
+ .invoke("css", "width")
963
+ .then((width) => parseInt(width))
964
+ .should("be.gte", 424)
965
+ .and("be.lte", 426);
966
+ cy.get(cesc("#\\/g"))
967
+ .invoke("css", "height")
968
+ .then((height) => parseInt(height))
969
+ .should("be.gte", 424)
970
+ .and("be.lte", 426);
971
+ });
972
+
973
+ cy.log("set aspect ratio to 2");
974
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
975
+ .type("{end}{backspace}2{enter}", { force: true })
976
+ .then(() => {
977
+ xmin = -60;
978
+ xmax = 60;
979
+ checkLimits(xmin, xmax, ymin, ymax);
980
+ cy.get(cesc("#\\/g"))
981
+ .invoke("css", "width")
982
+ .then((width) => parseInt(width))
983
+ .should("be.gte", 424)
984
+ .and("be.lte", 426);
985
+ cy.get(cesc("#\\/g"))
986
+ .invoke("css", "height")
987
+ .then((height) => parseInt(height))
988
+ .should("be.gte", 212)
989
+ .and("be.lte", 213);
990
+ });
991
+
992
+ cy.log("set aspect ratio to 1/2");
993
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
994
+ .type("{end}{backspace}1/2{enter}", { force: true })
995
+ .then(() => {
996
+ xmin = -15;
997
+ xmax = 15;
998
+ checkLimits(xmin, xmax, ymin, ymax);
999
+ cy.get(cesc("#\\/g"))
1000
+ .invoke("css", "width")
1001
+ .then((width) => parseInt(width))
1002
+ .should("be.gte", 424)
1003
+ .and("be.lte", 426);
1004
+ cy.get(cesc("#\\/g"))
1005
+ .invoke("css", "height")
1006
+ .then((height) => parseInt(height))
1007
+ .should("be.gte", 849)
1008
+ .and("be.lte", 851);
1009
+ });
1010
+
1011
+ cy.reload();
1012
+
1013
+ cy.log("xmin, xmax, ymin and ymax specified");
1014
+ cy.window().then(async (win) => {
1015
+ win.postMessage(
1016
+ {
1017
+ doenetML: `
1018
+ <text>h</text>
1019
+ <p>Aspect ratio: <mathinput name="aspectRatio" prefill="1" /></p>
1020
+
1021
+ <graph name="g" identicalAxisScales aspectRatio="$aspectRatio" xmin="-50" xmax="30" ymin='-20' ymax="40" />
1022
+
1023
+ <p>xmin: <copy prop="xmin" target="g" assignNames="xmin" /></p>
1024
+ <p>xmax: <copy prop="xmax" target="g" assignNames="xmax" /></p>
1025
+ <p>ymin: <copy prop="ymin" target="g" assignNames="ymin" /></p>
1026
+ <p>ymax: <copy prop="ymax" target="g" assignNames="ymax" /></p>
1027
+
1028
+ `,
1029
+ },
1030
+ "*",
1031
+ );
1032
+ });
1033
+
1034
+ //wait for page to load
1035
+ cy.get(cesc("#\\/_text1"))
1036
+ .should("have.text", "h")
1037
+ .then(() => {
1038
+ xmin = -50;
1039
+ xmax = 30;
1040
+ ymin = -20;
1041
+ ymax = 60;
1042
+ checkLimits(xmin, xmax, ymin, ymax);
1043
+ cy.get(cesc("#\\/g"))
1044
+ .invoke("css", "width")
1045
+ .then((width) => parseInt(width))
1046
+ .should("be.gte", 424)
1047
+ .and("be.lte", 426);
1048
+ cy.get(cesc("#\\/g"))
1049
+ .invoke("css", "height")
1050
+ .then((height) => parseInt(height))
1051
+ .should("be.gte", 424)
1052
+ .and("be.lte", 426);
1053
+ });
1054
+
1055
+ cy.log("set aspect ratio to 2");
1056
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
1057
+ .type("{end}{backspace}2{enter}", { force: true })
1058
+ .then(() => {
1059
+ xmax = 70;
1060
+ ymax = 40;
1061
+ checkLimits(xmin, xmax, ymin, ymax);
1062
+ cy.get(cesc("#\\/g"))
1063
+ .invoke("css", "width")
1064
+ .then((width) => parseInt(width))
1065
+ .should("be.gte", 424)
1066
+ .and("be.lte", 426);
1067
+ cy.get(cesc("#\\/g"))
1068
+ .invoke("css", "height")
1069
+ .then((height) => parseInt(height))
1070
+ .should("be.gte", 212)
1071
+ .and("be.lte", 213);
1072
+ });
1073
+
1074
+ cy.log("set aspect ratio to 1/2");
1075
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
1076
+ .type("{end}{backspace}1/2{enter}", { force: true })
1077
+ .then(() => {
1078
+ xmax = 30;
1079
+ ymax = 140;
1080
+ checkLimits(xmin, xmax, ymin, ymax);
1081
+ cy.get(cesc("#\\/g"))
1082
+ .invoke("css", "width")
1083
+ .then((width) => parseInt(width))
1084
+ .should("be.gte", 424)
1085
+ .and("be.lte", 426);
1086
+ cy.get(cesc("#\\/g"))
1087
+ .invoke("css", "height")
1088
+ .then((height) => parseInt(height))
1089
+ .should("be.gte", 849)
1090
+ .and("be.lte", 851);
1091
+ });
1092
+
1093
+ cy.reload();
1094
+
1095
+ cy.log("leave out xmin");
1096
+ cy.window().then(async (win) => {
1097
+ win.postMessage(
1098
+ {
1099
+ doenetML: `
1100
+ <text>i</text>
1101
+ <p>Aspect ratio: <mathinput name="aspectRatio" prefill="1" /></p>
1102
+
1103
+ <graph name="g" identicalAxisScales aspectRatio="$aspectRatio" xmax="30" ymin='-20' ymax="40" />
1104
+
1105
+ <p>xmin: <copy prop="xmin" target="g" assignNames="xmin" /></p>
1106
+ <p>xmax: <copy prop="xmax" target="g" assignNames="xmax" /></p>
1107
+ <p>ymin: <copy prop="ymin" target="g" assignNames="ymin" /></p>
1108
+ <p>ymax: <copy prop="ymax" target="g" assignNames="ymax" /></p>
1109
+
1110
+ `,
1111
+ },
1112
+ "*",
1113
+ );
1114
+ });
1115
+
1116
+ //wait for page to load
1117
+ cy.get(cesc("#\\/_text1"))
1118
+ .should("have.text", "i")
1119
+ .then(() => {
1120
+ xmin = -30;
1121
+ xmax = 30;
1122
+ ymin = -20;
1123
+ ymax = 40;
1124
+ checkLimits(xmin, xmax, ymin, ymax);
1125
+ cy.get(cesc("#\\/g"))
1126
+ .invoke("css", "width")
1127
+ .then((width) => parseInt(width))
1128
+ .should("be.gte", 424)
1129
+ .and("be.lte", 426);
1130
+ cy.get(cesc("#\\/g"))
1131
+ .invoke("css", "height")
1132
+ .then((height) => parseInt(height))
1133
+ .should("be.gte", 424)
1134
+ .and("be.lte", 426);
1135
+ });
1136
+
1137
+ cy.log("set aspect ratio to 2");
1138
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
1139
+ .type("{end}{backspace}2{enter}", { force: true })
1140
+ .then(() => {
1141
+ xmin = -90;
1142
+ checkLimits(xmin, xmax, ymin, ymax);
1143
+ cy.get(cesc("#\\/g"))
1144
+ .invoke("css", "width")
1145
+ .then((width) => parseInt(width))
1146
+ .should("be.gte", 424)
1147
+ .and("be.lte", 426);
1148
+ cy.get(cesc("#\\/g"))
1149
+ .invoke("css", "height")
1150
+ .then((height) => parseInt(height))
1151
+ .should("be.gte", 212)
1152
+ .and("be.lte", 213);
1153
+ });
1154
+
1155
+ cy.log("set aspect ratio to 1/2");
1156
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
1157
+ .type("{end}{backspace}1/2{enter}", { force: true })
1158
+ .then(() => {
1159
+ xmin = 0;
1160
+ checkLimits(xmin, xmax, ymin, ymax);
1161
+ cy.get(cesc("#\\/g"))
1162
+ .invoke("css", "width")
1163
+ .then((width) => parseInt(width))
1164
+ .should("be.gte", 424)
1165
+ .and("be.lte", 426);
1166
+ cy.get(cesc("#\\/g"))
1167
+ .invoke("css", "height")
1168
+ .then((height) => parseInt(height))
1169
+ .should("be.gte", 849)
1170
+ .and("be.lte", 851);
1171
+ });
1172
+
1173
+ cy.reload();
1174
+
1175
+ cy.log("leave out xmax");
1176
+ cy.window().then(async (win) => {
1177
+ win.postMessage(
1178
+ {
1179
+ doenetML: `
1180
+ <text>j</text>
1181
+ <p>Aspect ratio: <mathinput name="aspectRatio" prefill="1" /></p>
1182
+
1183
+ <graph name="g" identicalAxisScales aspectRatio="$aspectRatio" xmin="-30" ymin='-20' ymax="40" />
1184
+
1185
+ <p>xmin: <copy prop="xmin" target="g" assignNames="xmin" /></p>
1186
+ <p>xmax: <copy prop="xmax" target="g" assignNames="xmax" /></p>
1187
+ <p>ymin: <copy prop="ymin" target="g" assignNames="ymin" /></p>
1188
+ <p>ymax: <copy prop="ymax" target="g" assignNames="ymax" /></p>
1189
+
1190
+ `,
1191
+ },
1192
+ "*",
1193
+ );
1194
+ });
1195
+
1196
+ //wait for page to load
1197
+ cy.get(cesc("#\\/_text1"))
1198
+ .should("have.text", "j")
1199
+ .then(() => {
1200
+ xmin = -30;
1201
+ xmax = 30;
1202
+ ymin = -20;
1203
+ ymax = 40;
1204
+ checkLimits(xmin, xmax, ymin, ymax);
1205
+ cy.get(cesc("#\\/g"))
1206
+ .invoke("css", "width")
1207
+ .then((width) => parseInt(width))
1208
+ .should("be.gte", 424)
1209
+ .and("be.lte", 426);
1210
+ cy.get(cesc("#\\/g"))
1211
+ .invoke("css", "height")
1212
+ .then((height) => parseInt(height))
1213
+ .should("be.gte", 424)
1214
+ .and("be.lte", 426);
1215
+ });
1216
+
1217
+ cy.log("set aspect ratio to 2");
1218
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
1219
+ .type("{end}{backspace}2{enter}", { force: true })
1220
+ .then(() => {
1221
+ xmax = 90;
1222
+ checkLimits(xmin, xmax, ymin, ymax);
1223
+ cy.get(cesc("#\\/g"))
1224
+ .invoke("css", "width")
1225
+ .then((width) => parseInt(width))
1226
+ .should("be.gte", 424)
1227
+ .and("be.lte", 426);
1228
+ cy.get(cesc("#\\/g"))
1229
+ .invoke("css", "height")
1230
+ .then((height) => parseInt(height))
1231
+ .should("be.gte", 212)
1232
+ .and("be.lte", 213);
1233
+ });
1234
+
1235
+ cy.log("set aspect ratio to 1/2");
1236
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
1237
+ .type("{end}{backspace}1/2{enter}", { force: true })
1238
+ .then(() => {
1239
+ xmax = 0;
1240
+ checkLimits(xmin, xmax, ymin, ymax);
1241
+ cy.get(cesc("#\\/g"))
1242
+ .invoke("css", "width")
1243
+ .then((width) => parseInt(width))
1244
+ .should("be.gte", 424)
1245
+ .and("be.lte", 426);
1246
+ cy.get(cesc("#\\/g"))
1247
+ .invoke("css", "height")
1248
+ .then((height) => parseInt(height))
1249
+ .should("be.gte", 849)
1250
+ .and("be.lte", 851);
1251
+ });
1252
+
1253
+ cy.reload();
1254
+
1255
+ cy.log("leave out ymin");
1256
+ cy.window().then(async (win) => {
1257
+ win.postMessage(
1258
+ {
1259
+ doenetML: `
1260
+ <text>k</text>
1261
+ <p>Aspect ratio: <mathinput name="aspectRatio" prefill="1" /></p>
1262
+
1263
+ <graph name="g" identicalAxisScales aspectRatio="$aspectRatio" xmin="-50" xmax="30" ymax="40" />
1264
+
1265
+ <p>xmin: <copy prop="xmin" target="g" assignNames="xmin" /></p>
1266
+ <p>xmax: <copy prop="xmax" target="g" assignNames="xmax" /></p>
1267
+ <p>ymin: <copy prop="ymin" target="g" assignNames="ymin" /></p>
1268
+ <p>ymax: <copy prop="ymax" target="g" assignNames="ymax" /></p>
1269
+
1270
+ `,
1271
+ },
1272
+ "*",
1273
+ );
1274
+ });
1275
+
1276
+ //wait for page to load
1277
+ cy.get(cesc("#\\/_text1"))
1278
+ .should("have.text", "k")
1279
+ .then(() => {
1280
+ xmin = -50;
1281
+ xmax = 30;
1282
+ ymin = -40;
1283
+ ymax = 40;
1284
+ checkLimits(xmin, xmax, ymin, ymax);
1285
+ cy.get(cesc("#\\/g"))
1286
+ .invoke("css", "width")
1287
+ .then((width) => parseInt(width))
1288
+ .should("be.gte", 424)
1289
+ .and("be.lte", 426);
1290
+ cy.get(cesc("#\\/g"))
1291
+ .invoke("css", "height")
1292
+ .then((height) => parseInt(height))
1293
+ .should("be.gte", 424)
1294
+ .and("be.lte", 426);
1295
+ });
1296
+
1297
+ cy.log("set aspect ratio to 2");
1298
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
1299
+ .type("{end}{backspace}2{enter}", { force: true })
1300
+ .then(() => {
1301
+ ymin = 0;
1302
+ checkLimits(xmin, xmax, ymin, ymax);
1303
+ cy.get(cesc("#\\/g"))
1304
+ .invoke("css", "width")
1305
+ .then((width) => parseInt(width))
1306
+ .should("be.gte", 424)
1307
+ .and("be.lte", 426);
1308
+ cy.get(cesc("#\\/g"))
1309
+ .invoke("css", "height")
1310
+ .then((height) => parseInt(height))
1311
+ .should("be.gte", 212)
1312
+ .and("be.lte", 213);
1313
+ });
1314
+
1315
+ cy.log("set aspect ratio to 1/2");
1316
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
1317
+ .type("{end}{backspace}1/2{enter}", { force: true })
1318
+ .then(() => {
1319
+ ymin = -120;
1320
+ checkLimits(xmin, xmax, ymin, ymax);
1321
+ cy.get(cesc("#\\/g"))
1322
+ .invoke("css", "width")
1323
+ .then((width) => parseInt(width))
1324
+ .should("be.gte", 424)
1325
+ .and("be.lte", 426);
1326
+ cy.get(cesc("#\\/g"))
1327
+ .invoke("css", "height")
1328
+ .then((height) => parseInt(height))
1329
+ .should("be.gte", 849)
1330
+ .and("be.lte", 851);
1331
+ });
1332
+
1333
+ cy.reload();
1334
+
1335
+ cy.log("leave out ymax");
1336
+ cy.window().then(async (win) => {
1337
+ win.postMessage(
1338
+ {
1339
+ doenetML: `
1340
+ <text>l</text>
1341
+ <p>Aspect ratio: <mathinput name="aspectRatio" prefill="1" /></p>
1342
+
1343
+ <graph name="g" identicalAxisScales aspectRatio="$aspectRatio" xmin="-50" xmax="30" ymin="-40" />
1344
+
1345
+ <p>xmin: <copy prop="xmin" target="g" assignNames="xmin" /></p>
1346
+ <p>xmax: <copy prop="xmax" target="g" assignNames="xmax" /></p>
1347
+ <p>ymin: <copy prop="ymin" target="g" assignNames="ymin" /></p>
1348
+ <p>ymax: <copy prop="ymax" target="g" assignNames="ymax" /></p>
1349
+
1350
+ `,
1351
+ },
1352
+ "*",
1353
+ );
1354
+ });
1355
+
1356
+ //wait for page to load
1357
+ cy.get(cesc("#\\/_text1"))
1358
+ .should("have.text", "l")
1359
+ .then(() => {
1360
+ xmin = -50;
1361
+ xmax = 30;
1362
+ ymin = -40;
1363
+ ymax = 40;
1364
+ checkLimits(xmin, xmax, ymin, ymax);
1365
+ cy.get(cesc("#\\/g"))
1366
+ .invoke("css", "width")
1367
+ .then((width) => parseInt(width))
1368
+ .should("be.gte", 424)
1369
+ .and("be.lte", 426);
1370
+ cy.get(cesc("#\\/g"))
1371
+ .invoke("css", "height")
1372
+ .then((height) => parseInt(height))
1373
+ .should("be.gte", 424)
1374
+ .and("be.lte", 426);
1375
+ });
1376
+
1377
+ cy.log("set aspect ratio to 2");
1378
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
1379
+ .type("{end}{backspace}2{enter}", { force: true })
1380
+ .then(() => {
1381
+ ymax = 0;
1382
+ checkLimits(xmin, xmax, ymin, ymax);
1383
+ cy.get(cesc("#\\/g"))
1384
+ .invoke("css", "width")
1385
+ .then((width) => parseInt(width))
1386
+ .should("be.gte", 424)
1387
+ .and("be.lte", 426);
1388
+ cy.get(cesc("#\\/g"))
1389
+ .invoke("css", "height")
1390
+ .then((height) => parseInt(height))
1391
+ .should("be.gte", 212)
1392
+ .and("be.lte", 213);
1393
+ });
1394
+
1395
+ cy.log("set aspect ratio to 1/2");
1396
+ cy.get(cesc("#\\/aspectRatio") + " textarea")
1397
+ .type("{end}{backspace}1/2{enter}", { force: true })
1398
+ .then(() => {
1399
+ ymax = 120;
1400
+ checkLimits(xmin, xmax, ymin, ymax);
1401
+ cy.get(cesc("#\\/g"))
1402
+ .invoke("css", "width")
1403
+ .then((width) => parseInt(width))
1404
+ .should("be.gte", 424)
1405
+ .and("be.lte", 426);
1406
+ cy.get(cesc("#\\/g"))
1407
+ .invoke("css", "height")
1408
+ .then((height) => parseInt(height))
1409
+ .should("be.gte", 849)
1410
+ .and("be.lte", 851);
1411
+ });
1412
+ });
1413
+
1414
+ it("identical axis scales, without given aspect ratio", () => {
1415
+ cy.window().then(async (win) => {
1416
+ win.postMessage(
1417
+ {
1418
+ doenetML: `
1419
+ <text>a</text>
1420
+
1421
+ <graph name="g" identicalAxisScales />
1422
+
1423
+ <p>xmin: <copy prop="xmin" target="g" assignNames="xmin" /></p>
1424
+ <p>xmax: <copy prop="xmax" target="g" assignNames="xmax" /></p>
1425
+ <p>ymin: <copy prop="ymin" target="g" assignNames="ymin" /></p>
1426
+ <p>ymax: <copy prop="ymax" target="g" assignNames="ymax" /></p>
1427
+
1428
+ <p>Change xmin: <mathinput name="xminInput" bindValueTo="$g.xmin" /></p>
1429
+ <p>Change xmax: <mathinput name="xmaxInput" bindValueTo="$g.xmax" /></p>
1430
+ <p>Change ymin: <mathinput name="yminInput" bindValueTo="$g.ymin" /></p>
1431
+ <p>Change ymax: <mathinput name="ymaxInput" bindValueTo="$g.ymax" /></p>
1432
+
1433
+ `,
1434
+ },
1435
+ "*",
1436
+ );
1437
+ });
1438
+
1439
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
1440
+
1441
+ function checkLimits(xmin, xmax, ymin, ymax) {
1442
+ cy.get(cesc("#\\/xmin")).should("have.text", String(xmin));
1443
+ cy.get(cesc("#\\/xmax")).should("have.text", String(xmax));
1444
+ cy.get(cesc("#\\/ymin")).should("have.text", String(ymin));
1445
+ cy.get(cesc("#\\/ymax")).should("have.text", String(ymax));
1446
+
1447
+ cy.window().then(async (win) => {
1448
+ let stateVariables = await win.returnAllStateVariables1();
1449
+ expect(stateVariables["/g"].stateValues.xmin).eq(xmin);
1450
+ expect(stateVariables["/g"].stateValues.xmax).eq(xmax);
1451
+ expect(stateVariables["/g"].stateValues.ymin).eq(ymin);
1452
+ expect(stateVariables["/g"].stateValues.ymax).eq(ymax);
1453
+ });
1454
+ }
1455
+
1456
+ cy.get(cesc("#\\/g"))
1457
+ .invoke("css", "width")
1458
+ .then((width) => parseInt(width))
1459
+ .should("be.gte", 424)
1460
+ .and("be.lte", 426);
1461
+ cy.get(cesc("#\\/g"))
1462
+ .invoke("css", "height")
1463
+ .then((height) => parseInt(height))
1464
+ .should("be.gte", 424)
1465
+ .and("be.lte", 426);
1466
+
1467
+ checkLimits(-10, 10, -10, 10);
1468
+
1469
+ cy.log("set xmin to -5");
1470
+ cy.get(cesc("#\\/xminInput") + " textarea").type(
1471
+ "{ctrl+home}{shift+ctrl+end}{backspace}-5{enter}",
1472
+ { force: true },
1473
+ );
1474
+
1475
+ cy.get(cesc("#\\/xmin")).should("have.text", "-5");
1476
+ cy.get(cesc("#\\/g"))
1477
+ .invoke("css", "width")
1478
+ .then((width) => parseInt(width))
1479
+ .should("be.gte", 424)
1480
+ .and("be.lte", 426);
1481
+ cy.get(cesc("#\\/g"))
1482
+ .invoke("css", "height")
1483
+ .then((height) => parseInt(height))
1484
+ .should("be.gte", 566)
1485
+ .and("be.lte", 567);
1486
+
1487
+ checkLimits(-5, 10, -10, 10);
1488
+
1489
+ cy.log("set ymax to 0");
1490
+ cy.get(cesc("#\\/ymaxInput") + " textarea").type(
1491
+ "{ctrl+home}{shift+ctrl+end}{backspace}0{enter}",
1492
+ { force: true },
1493
+ );
1494
+
1495
+ cy.get(cesc("#\\/ymax")).should("have.text", "0");
1496
+ cy.get(cesc("#\\/g"))
1497
+ .invoke("css", "width")
1498
+ .then((width) => parseInt(width))
1499
+ .should("be.gte", 424)
1500
+ .and("be.lte", 426);
1501
+ cy.get(cesc("#\\/g"))
1502
+ .invoke("css", "height")
1503
+ .then((height) => parseInt(height))
1504
+ .should("be.gte", 283)
1505
+ .and("be.lte", 284);
1506
+
1507
+ checkLimits(-5, 10, -10, 0);
1508
+ });
1509
+
1510
+ it("show grid", () => {
1511
+ cy.window().then(async (win) => {
1512
+ win.postMessage(
1513
+ {
1514
+ doenetML: `
1515
+ <text>a</text>
1516
+
1517
+ <graph name="g1">
1518
+ </graph>
1519
+ <p>Graph 1 has grid: <copy prop="grid" target="g1" assignNames="sg1" /></p>
1520
+
1521
+ <graph name="g2" grid="none">
1522
+ </graph>
1523
+ <p>Graph 2 has grid: <copy prop="grid" target="g2" assignNames="sg2" /></p>
1524
+
1525
+ <graph name="g3" grid>
1526
+ </graph>
1527
+ <p>Graph 3 has grid: <copy prop="grid" target="g3" assignNames="sg3" /></p>
1528
+
1529
+ <graph name="g4" grid="medium">
1530
+ </graph>
1531
+ <p>Graph 4 has grid: <copy prop="grid" target="g4" assignNames="sg4" /></p>
1532
+
1533
+ <graph name="g5" grid="dense">
1534
+ </graph>
1535
+ <p>Graph 5 has grid: <copy prop="grid" target="g5" assignNames="sg5" /></p>
1536
+
1537
+
1538
+ <p>Show grid: <booleanInput name="bi" /></p>
1539
+ <graph name="g6" grid="$bi">
1540
+ </graph>
1541
+ <p>Graph 6 has grid: <copy prop="grid" target="g6" assignNames="sg6" /></p>
1542
+
1543
+
1544
+ <p>Show grid: <textinput name="ti" /></p>
1545
+ <graph name="g7" grid="$ti">
1546
+ </graph>
1547
+ <p>Graph 7 has grid: <copy prop="grid" target="g7" assignNames="sg7" /></p>
1548
+
1549
+ `,
1550
+ },
1551
+ "*",
1552
+ );
1553
+ });
1554
+
1555
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
1556
+
1557
+ // not sure what to test as don't know how to check renderer...
1558
+ cy.get(cesc("#\\/sg1")).should("have.text", "none");
1559
+ cy.get(cesc("#\\/sg2")).should("have.text", "none");
1560
+ cy.get(cesc("#\\/sg3")).should("have.text", "medium");
1561
+ cy.get(cesc("#\\/sg4")).should("have.text", "medium");
1562
+ cy.get(cesc("#\\/sg5")).should("have.text", "dense");
1563
+ cy.get(cesc("#\\/sg6")).should("have.text", "none");
1564
+ cy.get(cesc("#\\/sg7")).should("have.text", "none");
1565
+
1566
+ cy.get(cesc("#\\/bi")).click();
1567
+ cy.get(cesc("#\\/sg6")).should("have.text", "medium");
1568
+
1569
+ cy.get(cesc("#\\/ti_input")).type("true{enter}");
1570
+ cy.get(cesc("#\\/sg7")).should("have.text", "medium");
1571
+
1572
+ cy.get(cesc("#\\/ti_input")).clear().type("false{enter}");
1573
+ cy.get(cesc("#\\/sg7")).should("have.text", "none");
1574
+
1575
+ cy.get(cesc("#\\/ti_input")).clear().type("dense{enter}");
1576
+ cy.get(cesc("#\\/sg7")).should("have.text", "dense");
1577
+
1578
+ cy.get(cesc("#\\/ti_input")).clear().type("hello{enter}");
1579
+ cy.get(cesc("#\\/sg7")).should("have.text", "none");
1580
+
1581
+ cy.get(cesc("#\\/ti_input")).clear().type("medium{enter}");
1582
+ cy.get(cesc("#\\/sg7")).should("have.text", "medium");
1583
+
1584
+ cy.get(cesc("#\\/ti_input")).clear().type("none{enter}");
1585
+ cy.get(cesc("#\\/sg7")).should("have.text", "none");
1586
+ });
1587
+
1588
+ it("fixed grids", () => {
1589
+ cy.window().then(async (win) => {
1590
+ win.postMessage(
1591
+ {
1592
+ doenetML: `
1593
+ <text>a</text>
1594
+
1595
+ <graph name="g1" grid="1 pi/2" displayDigits="4">
1596
+ </graph>
1597
+ <p>Graph 1 has grid: <copy prop="grid" target="g1" assignNames="sg1" /></p>
1598
+
1599
+ <p>grid x: <mathinput name="g2x" /></p>
1600
+ <p>grid y: <mathinput name="g2y" /></p>
1601
+ <graph name="g2" grid="$g2x $g2y">
1602
+ </graph>
1603
+ <p>Graph 2 has grid: <copy prop="grid" target="g2" assignNames="sg2" /></p>
1604
+
1605
+ <p>grid x: <mathinput name="g3x" /> <number name="g3xa" hide>$g3x</number></p>
1606
+ <p>grid y: <mathinput name="g3y" /> <number name="g3ya" hide>$g3y</number></p>
1607
+ <graph name="g3" grid="$g3xa $g3ya">
1608
+ </graph>
1609
+ <p>Graph 3 has grid: <copy prop="grid" target="g3" assignNames="sg3" /></p>
1610
+
1611
+ <p>grid x: <mathinput name="g4x" prefill="1" /></p>
1612
+ <p>grid y: <mathinput name="g4y" prefill="1" /></p>
1613
+ <graph name="g4" grid="2$g4x 3$g4y" displayDecimals="2">
1614
+ </graph>
1615
+ <p>Graph 4 has grid: <copy prop="grid" target="g4" assignNames="sg4" /></p>
1616
+
1617
+ <p>grid x: <mathinput name="g5x" prefill="1" /> <number name="g5xa">$g5x</number></p>
1618
+ <p>grid y: <mathinput name="g5y" prefill="1" /> <number name="g5ya">$g5y</number></p>
1619
+ <graph name="g5" grid="2$g5xa 3$g5ya" displayDecimals="2">
1620
+ </graph>
1621
+ <p>Graph 5 has grid: <copy prop="grid" target="g5" assignNames="sg5" /></p>
1622
+
1623
+ `,
1624
+ },
1625
+ "*",
1626
+ );
1627
+ });
1628
+
1629
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
1630
+
1631
+ cy.get(cesc("#\\/sg1")).should("have.text", "1, 1.571");
1632
+ cy.get(cesc("#\\/sg2")).should("have.text", "none");
1633
+ cy.get(cesc("#\\/sg3")).should("have.text", "none");
1634
+ cy.get(cesc("#\\/sg4")).should("have.text", "2, 3");
1635
+ cy.get(cesc("#\\/sg5")).should("have.text", "2, 3");
1636
+
1637
+ cy.get(cesc("#\\/g2x") + " textarea").type("3", { force: true });
1638
+ cy.get(cesc("#\\/g2y") + " textarea")
1639
+ .type("1.5", { force: true })
1640
+ .blur();
1641
+ cy.get(cesc("#\\/sg2")).should("have.text", "3, 1.5");
1642
+
1643
+ cy.get(cesc("#\\/g3x") + " textarea").type("3", { force: true });
1644
+ cy.get(cesc("#\\/g3y") + " textarea")
1645
+ .type("1.5", { force: true })
1646
+ .blur();
1647
+ cy.get(cesc("#\\/sg3")).should("have.text", "3, 1.5");
1648
+
1649
+ cy.get(cesc("#\\/g4x") + " textarea").type("{end}{backspace}3", {
1650
+ force: true,
1651
+ });
1652
+ cy.get(cesc("#\\/g4y") + " textarea")
1653
+ .type("{end}.5", { force: true })
1654
+ .blur();
1655
+ cy.get(cesc("#\\/sg4")).should("have.text", "6, 4.5");
1656
+
1657
+ cy.get(cesc("#\\/g5x") + " textarea").type("{end}{backspace}3", {
1658
+ force: true,
1659
+ });
1660
+ cy.get(cesc("#\\/g5y") + " textarea")
1661
+ .type("{end}.5", { force: true })
1662
+ .blur();
1663
+ cy.get(cesc("#\\/sg5")).should("have.text", "6, 4.5");
1664
+
1665
+ cy.get(cesc("#\\/g2x") + " textarea").type("{end}e/2", { force: true });
1666
+ cy.get(cesc("#\\/g2y") + " textarea")
1667
+ .type("{end}pi", { force: true })
1668
+ .blur();
1669
+ cy.get(cesc("#\\/sg2")).should("have.text", "4.08, 4.71");
1670
+
1671
+ cy.get(cesc("#\\/g3x") + " textarea").type("{end}e/2", { force: true });
1672
+ cy.get(cesc("#\\/g3y") + " textarea")
1673
+ .type("{end}pi", { force: true })
1674
+ .blur();
1675
+ cy.get(cesc("#\\/sg3")).should("have.text", "4.08, 4.71");
1676
+
1677
+ cy.get(cesc("#\\/g4x") + " textarea").type("{end}pi/5", { force: true });
1678
+ cy.get(cesc("#\\/g4y") + " textarea")
1679
+ .type("{end}e/6", { force: true })
1680
+ .blur();
1681
+ cy.get(cesc("#\\/sg4")).should("have.text", "3.77, 2.04");
1682
+
1683
+ cy.get(cesc("#\\/g5x") + " textarea").type("{end}pi/5", { force: true });
1684
+ cy.get(cesc("#\\/g5y") + " textarea")
1685
+ .type("{end}e/6", { force: true })
1686
+ .blur();
1687
+ cy.get(cesc("#\\/sg5")).should("have.text", "3.77, 2.04");
1688
+ });
1689
+
1690
+ // check for bug in placeholder adapter
1691
+ it("graph with label as submitted response, createComponentOfType specified", () => {
1692
+ cy.window().then(async (win) => {
1693
+ win.postMessage(
1694
+ {
1695
+ doenetML: `
1696
+ <text>a</text>
1697
+ <graph>
1698
+ <xlabel>$(x.submittedResponse{ createComponentOfType='math'})</xlabel>
1699
+ <ylabel>y</ylabel>
1700
+ </graph>
1701
+
1702
+ <answer name="x">x</answer>
1703
+ <copy prop="submittedResponse" target="x" assignNames="sr" />
1704
+
1705
+ `,
1706
+ },
1707
+ "*",
1708
+ );
1709
+ });
1710
+
1711
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
1712
+
1713
+ // not sure what to test as don't know how to check renderer...
1714
+ // but main thing is that don't have an error
1715
+
1716
+ cy.window().then(async (win) => {
1717
+ let stateVariables = await win.returnAllStateVariables1();
1718
+ expect(stateVariables["/_graph1"].stateValues.xlabel).eq("\\(\uff3f\\)");
1719
+
1720
+ let mathinputName =
1721
+ stateVariables["/x"].stateValues.inputChildren[0].componentName;
1722
+ let mathinputAnchor = cesc2("#" + mathinputName) + " textarea";
1723
+
1724
+ cy.get(mathinputAnchor).type("x{enter}", { force: true });
1725
+
1726
+ cy.get(cesc("#\\/sr") + " .mjx-mrow").should("contain.text", "x");
1727
+ cy.window().then(async (win) => {
1728
+ let stateVariables = await win.returnAllStateVariables1();
1729
+ expect(stateVariables["/_graph1"].stateValues.xlabel).eq("\\(x\\)");
1730
+ });
1731
+ });
1732
+ });
1733
+
1734
+ it("display tick labels", () => {
1735
+ cy.window().then(async (win) => {
1736
+ win.postMessage(
1737
+ {
1738
+ doenetML: `
1739
+ <text>a</text>
1740
+
1741
+ <graph displayXAxisTickLabels="$b1" displayYAxisTickLabels="$b2">
1742
+ </graph>
1743
+ <booleaninput name="b1" />
1744
+ <copy prop="displayXAxisTickLabels" target="_graph1" assignNames="b1a" />
1745
+ <booleaninput name="b2" prefill="true" />
1746
+ <copy prop="displayYAxisTickLabels" target="_graph1" assignNames="b2a" />
1747
+
1748
+
1749
+ `,
1750
+ },
1751
+ "*",
1752
+ );
1753
+ });
1754
+
1755
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
1756
+
1757
+ // not sure what to test as don't know how to check renderer...
1758
+ cy.get(cesc("#\\/b1a")).should("have.text", "false");
1759
+ cy.get(cesc("#\\/b2a")).should("have.text", "true");
1760
+ cy.window().then(async (win) => {
1761
+ let stateVariables = await win.returnAllStateVariables1();
1762
+ expect(stateVariables["/_graph1"].stateValues.displayXAxisTickLabels).eq(
1763
+ false,
1764
+ );
1765
+ expect(stateVariables["/_graph1"].stateValues.displayYAxisTickLabels).eq(
1766
+ true,
1767
+ );
1768
+ });
1769
+
1770
+ cy.get(cesc("#\\/b1")).click();
1771
+
1772
+ cy.get(cesc("#\\/b1a")).should("have.text", "true");
1773
+ cy.get(cesc("#\\/b2a")).should("have.text", "true");
1774
+ cy.window().then(async (win) => {
1775
+ let stateVariables = await win.returnAllStateVariables1();
1776
+ expect(stateVariables["/_graph1"].stateValues.displayXAxisTickLabels).eq(
1777
+ true,
1778
+ );
1779
+ expect(stateVariables["/_graph1"].stateValues.displayYAxisTickLabels).eq(
1780
+ true,
1781
+ );
1782
+ });
1783
+
1784
+ cy.get(cesc("#\\/b2")).click();
1785
+
1786
+ cy.get(cesc("#\\/b1a")).should("have.text", "true");
1787
+ cy.get(cesc("#\\/b2a")).should("have.text", "false");
1788
+ cy.window().then(async (win) => {
1789
+ let stateVariables = await win.returnAllStateVariables1();
1790
+ expect(stateVariables["/_graph1"].stateValues.displayXAxisTickLabels).eq(
1791
+ true,
1792
+ );
1793
+ expect(stateVariables["/_graph1"].stateValues.displayYAxisTickLabels).eq(
1794
+ false,
1795
+ );
1796
+ });
1797
+
1798
+ cy.get(cesc("#\\/b1")).click();
1799
+
1800
+ cy.get(cesc("#\\/b1a")).should("have.text", "false");
1801
+ cy.get(cesc("#\\/b2a")).should("have.text", "false");
1802
+ cy.window().then(async (win) => {
1803
+ let stateVariables = await win.returnAllStateVariables1();
1804
+ expect(stateVariables["/_graph1"].stateValues.displayXAxisTickLabels).eq(
1805
+ false,
1806
+ );
1807
+ expect(stateVariables["/_graph1"].stateValues.displayYAxisTickLabels).eq(
1808
+ false,
1809
+ );
1810
+ });
1811
+
1812
+ cy.get(cesc("#\\/b2")).click();
1813
+
1814
+ cy.get(cesc("#\\/b1a")).should("have.text", "false");
1815
+ cy.get(cesc("#\\/b2a")).should("have.text", "true");
1816
+ cy.window().then(async (win) => {
1817
+ let stateVariables = await win.returnAllStateVariables1();
1818
+ expect(stateVariables["/_graph1"].stateValues.displayXAxisTickLabels).eq(
1819
+ false,
1820
+ );
1821
+ expect(stateVariables["/_graph1"].stateValues.displayYAxisTickLabels).eq(
1822
+ true,
1823
+ );
1824
+ });
1825
+ });
1826
+
1827
+ it("graph sizes", () => {
1828
+ cy.window().then(async (win) => {
1829
+ win.postMessage(
1830
+ {
1831
+ doenetML: `
1832
+ <text>a</text>
1833
+
1834
+ <graph name="g" />
1835
+
1836
+ <graph name="gtiny" size="tiny" />
1837
+ <graph name="gsmall" size="small" />
1838
+ <graph name="gmedium" size="medium" />
1839
+ <graph name="glarge" size="large" />
1840
+ <graph name="gfull" size="full" />
1841
+ <graph name="ginvalid" size="invalid" />
1842
+
1843
+ <graph name="ga10" width="10" />
1844
+ <graph name="ga100" width="100" />
1845
+ <graph name="ga200" width="200" />
1846
+ <graph name="ga300" width="300" />
1847
+ <graph name="ga400" width="400" />
1848
+ <graph name="ga500" width="500" />
1849
+ <graph name="ga600" width="600" />
1850
+ <graph name="ga700" width="700" />
1851
+ <graph name="ga800" width="800" />
1852
+ <graph name="ga900" width="900" />
1853
+ <graph name="ga10000" width="10000" />
1854
+
1855
+ <graph name="gp1" width="1%" />
1856
+ <graph name="gp10" width="10%" />
1857
+ <graph name="gp20" width="20%" />
1858
+ <graph name="gp30" width="30%" />
1859
+ <graph name="gp40" width="40%" />
1860
+ <graph name="gp50" width="50%" />
1861
+ <graph name="gp60" width="60%" />
1862
+ <graph name="gp70" width="70%" />
1863
+ <graph name="gp80" width="80%" />
1864
+ <graph name="gp90" width="90%" />
1865
+ <graph name="gp100" width="100%" />
1866
+ <graph name="gp1000" width="1000%" />
1867
+
1868
+ <graph name="gbadwidth" width="bad" />
1869
+
1870
+ `,
1871
+ },
1872
+ "*",
1873
+ );
1874
+ });
1875
+
1876
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
1877
+
1878
+ let expectedSizes = {
1879
+ g: "medium",
1880
+ gtiny: "tiny",
1881
+ gsmall: "small",
1882
+ gmedium: "medium",
1883
+ glarge: "large",
1884
+ gfull: "full",
1885
+ ginvalid: "medium",
1886
+ ga10: "tiny",
1887
+ ga100: "tiny",
1888
+ ga200: "small",
1889
+ ga300: "small",
1890
+ ga400: "medium",
1891
+ ga500: "medium",
1892
+ ga600: "large",
1893
+ ga700: "large",
1894
+ ga800: "full",
1895
+ ga900: "full",
1896
+ ga10000: "full",
1897
+ gp1: "tiny",
1898
+ gp10: "tiny",
1899
+ gp20: "small",
1900
+ gp30: "small",
1901
+ gp40: "small",
1902
+ gp50: "medium",
1903
+ gp60: "medium",
1904
+ gp70: "large",
1905
+ gp80: "large",
1906
+ gp90: "full",
1907
+ gp100: "full",
1908
+ gp1000: "full",
1909
+ gbadwidth: "medium",
1910
+ };
1911
+
1912
+ cy.window().then(async (win) => {
1913
+ let stateVariables = await win.returnAllStateVariables1();
1914
+ for (let name in expectedSizes) {
1915
+ expect(stateVariables["/" + name].stateValues.size).eq(
1916
+ expectedSizes[name],
1917
+ );
1918
+ }
1919
+ });
1920
+
1921
+ for (let name in expectedSizes) {
1922
+ cy.get(cesc2("#/" + name))
1923
+ .invoke("css", "width")
1924
+ .then((width) => parseInt(width))
1925
+ .should("be.gte", widthsBySize[expectedSizes[name]] - 4)
1926
+ .and("be.lte", widthsBySize[expectedSizes[name]] + 1);
1927
+ }
1928
+ });
1929
+
1930
+ it("horizontal align", () => {
1931
+ cy.window().then(async (win) => {
1932
+ win.postMessage(
1933
+ {
1934
+ doenetML: `
1935
+ <text>a</text>
1936
+
1937
+ <graph name="g" />
1938
+ <graph name="gleft" horizontalAlign="left" />
1939
+ <graph name="gright" horizontalAlign="right" />
1940
+ <graph name="gcenter" horizontalAlign="center" />
1941
+ <graph name="ginvalid" horizontalAlign="invalid" />
1942
+
1943
+ `,
1944
+ },
1945
+ "*",
1946
+ );
1947
+ });
1948
+
1949
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
1950
+
1951
+ cy.window().then(async (win) => {
1952
+ let stateVariables = await win.returnAllStateVariables1();
1953
+ expect(stateVariables["/g"].stateValues.horizontalAlign).eq("center");
1954
+ expect(stateVariables["/gleft"].stateValues.horizontalAlign).eq("left");
1955
+ expect(stateVariables["/gright"].stateValues.horizontalAlign).eq("right");
1956
+ expect(stateVariables["/gcenter"].stateValues.horizontalAlign).eq(
1957
+ "center",
1958
+ );
1959
+ expect(stateVariables["/ginvalid"].stateValues.horizontalAlign).eq(
1960
+ "center",
1961
+ );
1962
+ });
1963
+
1964
+ // TODO: anything to check in the DOM?
1965
+ });
1966
+
1967
+ it("displayMode", () => {
1968
+ cy.window().then(async (win) => {
1969
+ win.postMessage(
1970
+ {
1971
+ doenetML: `
1972
+ <text>a</text>
1973
+
1974
+ <graph name="g" />
1975
+ <graph name="ginline" displayMode="inline" />
1976
+ <graph name="gblock" displayMode="block" />
1977
+ <graph name="ginvalid" displayMode="invalid" />
1978
+
1979
+ `,
1980
+ },
1981
+ "*",
1982
+ );
1983
+ });
1984
+
1985
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
1986
+
1987
+ cy.window().then(async (win) => {
1988
+ let stateVariables = await win.returnAllStateVariables1();
1989
+ expect(stateVariables["/g"].stateValues.displayMode).eq("block");
1990
+ expect(stateVariables["/ginline"].stateValues.displayMode).eq("inline");
1991
+ expect(stateVariables["/gblock"].stateValues.displayMode).eq("block");
1992
+ expect(stateVariables["/ginvalid"].stateValues.displayMode).eq("block");
1993
+ });
1994
+
1995
+ // TODO: anything to check in the DOM?
1996
+ });
1997
+
1998
+ it("tick scale factor", () => {
1999
+ cy.window().then(async (win) => {
2000
+ win.postMessage(
2001
+ {
2002
+ doenetML: `
2003
+ <text>a</text>
2004
+
2005
+ <graph name="none" />
2006
+
2007
+ <graph name="xpi" xTickScaleFactor="pi" />
2008
+ <graph name="ypi" yTickScaleFactor="pi" />
2009
+ <graph name="bothpi" xTickScaleFactor="pi" yTickScaleFactor="pi" />
2010
+
2011
+ <graph name="xe" xTickScaleFactor="e" />
2012
+ <graph name="ye" yTickScaleFactor="e" />
2013
+ <graph name="bothe" xTickScaleFactor="e" yTickScaleFactor="e" />
2014
+
2015
+ <graph name="ignorebad" xTickScaleFactor="x" yTickScaleFactor="/" displayDigits="5" />
2016
+
2017
+ <copy prop="xmin" target="ignorebad" assignNames="xmin" />
2018
+ <copy prop="xmax" target="ignorebad" assignNames="xmax" />
2019
+ <copy prop="ymin" target="ignorebad" assignNames="ymin" />
2020
+ <copy prop="ymax" target="ignorebad" assignNames="ymax" />
2021
+
2022
+
2023
+
2024
+ `,
2025
+ },
2026
+ "*",
2027
+ );
2028
+ });
2029
+
2030
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
2031
+
2032
+ // Note: these are brittle tests and could start failing if internals of jsxgraph changes
2033
+
2034
+ cy.get(cesc("#\\/none")).should("not.contain.text", "π");
2035
+ cy.get(cesc("#\\/none")).should("not.contain.text", "e");
2036
+ cy.get(cesc("#\\/none")).should("contain.text", "68");
2037
+ cy.get(cesc("#\\/none")).should("contain.text", "−2−4−6−8");
2038
+
2039
+ cy.get(cesc("#\\/xpi")).should("contain.text", "π2π3π");
2040
+ cy.get(cesc("#\\/xpi")).should("contain.text", "−π−2π−3π");
2041
+ cy.get(cesc("#\\/xpi")).should("contain.text", "24");
2042
+ cy.get(cesc("#\\/xpi")).should("contain.text", "68");
2043
+ cy.get(cesc("#\\/xpi")).should("contain.text", "−2−4−6−8");
2044
+
2045
+ cy.get(cesc("#\\/ypi")).should("contain.text", "π2π3π");
2046
+ cy.get(cesc("#\\/ypi")).should("contain.text", "−π−2π−3π");
2047
+ cy.get(cesc("#\\/ypi")).should("contain.text", "24");
2048
+ cy.get(cesc("#\\/ypi")).should("contain.text", "68");
2049
+ cy.get(cesc("#\\/ypi")).should("contain.text", "−2−4−6−8");
2050
+
2051
+ cy.get(cesc("#\\/bothpi")).should("contain.text", "π2π3π");
2052
+ cy.get(cesc("#\\/bothpi")).should("contain.text", "−π−2π−3π");
2053
+ cy.get(cesc("#\\/bothpi")).should("not.contain.text", "24");
2054
+ cy.get(cesc("#\\/bothpi")).should("not.contain.text", "68");
2055
+ cy.get(cesc("#\\/bothpi")).should("not.contain.text", "−2−4−6−8");
2056
+
2057
+ cy.get(cesc("#\\/xe")).should("contain.text", "e2e3e");
2058
+ cy.get(cesc("#\\/xe")).should("contain.text", "−e−2e−3e");
2059
+ cy.get(cesc("#\\/xe")).should("contain.text", "24");
2060
+ cy.get(cesc("#\\/xe")).should("contain.text", "68");
2061
+ cy.get(cesc("#\\/xe")).should("contain.text", "−2−4−6−8");
2062
+
2063
+ cy.get(cesc("#\\/ye")).should("contain.text", "e2e3e");
2064
+ cy.get(cesc("#\\/ye")).should("contain.text", "−e−2e−3e");
2065
+ cy.get(cesc("#\\/ye")).should("contain.text", "24");
2066
+ cy.get(cesc("#\\/ye")).should("contain.text", "68");
2067
+ cy.get(cesc("#\\/ye")).should("contain.text", "−2−4−6−8");
2068
+
2069
+ cy.get(cesc("#\\/bothe")).should("contain.text", "e2e3e");
2070
+ cy.get(cesc("#\\/bothe")).should("contain.text", "−e−2e−3e");
2071
+ cy.get(cesc("#\\/bothe")).should("not.contain.text", "24");
2072
+ cy.get(cesc("#\\/bothe")).should("not.contain.text", "68");
2073
+ cy.get(cesc("#\\/bothe")).should("not.contain.text", "−2−4−6−8");
2074
+
2075
+ cy.get(cesc("#\\/ignorebad")).should("not.contain.text", "π");
2076
+ cy.get(cesc("#\\/ignorebad")).should("not.contain.text", "e");
2077
+ cy.get(cesc("#\\/ignorebad")).should("contain.text", "68");
2078
+ cy.get(cesc("#\\/ignorebad")).should("contain.text", "−2−4−6−8");
2079
+
2080
+ cy.get(cesc("#\\/none_navigationbar") + " > :nth-child(1)").click();
2081
+ cy.get(cesc("#\\/xpi_navigationbar") + " > :nth-child(1)").click();
2082
+ cy.get(cesc("#\\/ypi_navigationbar") + " > :nth-child(1)").click();
2083
+ cy.get(cesc("#\\/bothpi_navigationbar") + " > :nth-child(1)").click();
2084
+ cy.get(cesc("#\\/xe_navigationbar") + " > :nth-child(1)").click();
2085
+ cy.get(cesc("#\\/ye_navigationbar") + " > :nth-child(1)").click();
2086
+ cy.get(cesc("#\\/bothe_navigationbar") + " > :nth-child(1)").click();
2087
+ cy.get(cesc("#\\/ignorebad_navigationbar") + " > :nth-child(1)").click();
2088
+
2089
+ cy.get(cesc("#\\/xmax")).should("have.text", "12.5");
2090
+
2091
+ cy.get(cesc("#\\/none")).should("not.contain.text", "π");
2092
+ cy.get(cesc("#\\/none")).should("not.contain.text", "e");
2093
+ cy.get(cesc("#\\/none")).should("contain.text", "10");
2094
+ cy.get(cesc("#\\/none")).should("contain.text", "−10");
2095
+
2096
+ cy.get(cesc("#\\/xpi")).should("contain.text", "π2π3π");
2097
+ cy.get(cesc("#\\/xpi")).should("contain.text", "−π−2π−3π");
2098
+ cy.get(cesc("#\\/xpi")).should("contain.text", "10");
2099
+ cy.get(cesc("#\\/xpi")).should("contain.text", "−10");
2100
+
2101
+ cy.get(cesc("#\\/ypi")).should("contain.text", "π2π3π");
2102
+ cy.get(cesc("#\\/ypi")).should("contain.text", "−π−2π−3π");
2103
+ cy.get(cesc("#\\/ypi")).should("contain.text", "10");
2104
+ cy.get(cesc("#\\/ypi")).should("contain.text", "−10");
2105
+
2106
+ cy.get(cesc("#\\/bothpi")).should("contain.text", "π2π3π");
2107
+ cy.get(cesc("#\\/bothpi")).should("contain.text", "−π−2π−3π");
2108
+ cy.get(cesc("#\\/bothpi")).should("not.contain.text", "10");
2109
+ cy.get(cesc("#\\/bothpi")).should("not.contain.text", "−10");
2110
+
2111
+ cy.get(cesc("#\\/xe")).should("contain.text", "e2e3e4e");
2112
+ cy.get(cesc("#\\/xe")).should("contain.text", "−e−2e");
2113
+ cy.get(cesc("#\\/xe")).should("contain.text", "−3e−4e");
2114
+ cy.get(cesc("#\\/xe")).should("contain.text", "10");
2115
+ cy.get(cesc("#\\/xe")).should("contain.text", "−10");
2116
+
2117
+ cy.get(cesc("#\\/ye")).should("contain.text", "e2e3e4e");
2118
+ cy.get(cesc("#\\/ye")).should("contain.text", "−e−2e");
2119
+ cy.get(cesc("#\\/ye")).should("contain.text", "−3e−4e");
2120
+ cy.get(cesc("#\\/ye")).should("contain.text", "10");
2121
+ cy.get(cesc("#\\/ye")).should("contain.text", "−10");
2122
+
2123
+ cy.get(cesc("#\\/bothe")).should("contain.text", "e2e3e4e");
2124
+ cy.get(cesc("#\\/bothe")).should("contain.text", "−e−2e");
2125
+ cy.get(cesc("#\\/bothe")).should("contain.text", "−3e−4e");
2126
+ cy.get(cesc("#\\/bothe")).should("not.contain.text", "10");
2127
+ cy.get(cesc("#\\/bothe")).should("not.contain.text", "−10");
2128
+
2129
+ cy.get(cesc("#\\/ignorebad")).should("not.contain.text", "π");
2130
+ cy.get(cesc("#\\/ignorebad")).should("not.contain.text", "e");
2131
+ cy.get(cesc("#\\/ignorebad")).should("contain.text", "10");
2132
+ cy.get(cesc("#\\/ignorebad")).should("contain.text", "−10");
2133
+
2134
+ cy.get(cesc("#\\/none_navigationbar") + " > :nth-child(1)").click();
2135
+ cy.get(cesc("#\\/xpi_navigationbar") + " > :nth-child(1)").click();
2136
+ cy.get(cesc("#\\/ypi_navigationbar") + " > :nth-child(1)").click();
2137
+ cy.get(cesc("#\\/bothpi_navigationbar") + " > :nth-child(1)").click();
2138
+ cy.get(cesc("#\\/xe_navigationbar") + " > :nth-child(1)").click();
2139
+ cy.get(cesc("#\\/ye_navigationbar") + " > :nth-child(1)").click();
2140
+ cy.get(cesc("#\\/bothe_navigationbar") + " > :nth-child(1)").click();
2141
+ cy.get(cesc("#\\/ignorebad_navigationbar") + " > :nth-child(1)").click();
2142
+
2143
+ cy.get(cesc("#\\/xmax")).should("have.text", "15.625");
2144
+
2145
+ cy.get(cesc("#\\/none")).should("not.contain.text", "π");
2146
+ cy.get(cesc("#\\/none")).should("not.contain.text", "e");
2147
+ cy.get(cesc("#\\/none")).should("contain.text", "10");
2148
+ cy.get(cesc("#\\/none")).should("contain.text", "−10");
2149
+
2150
+ cy.get(cesc("#\\/xpi")).should("contain.text", "π2π3π4π");
2151
+ cy.get(cesc("#\\/xpi")).should("contain.text", "−π−2π");
2152
+ cy.get(cesc("#\\/xpi")).should("contain.text", "−3π−4π");
2153
+ cy.get(cesc("#\\/xpi")).should("contain.text", "10");
2154
+ cy.get(cesc("#\\/xpi")).should("contain.text", "−10");
2155
+
2156
+ cy.get(cesc("#\\/ypi")).should("contain.text", "π2π3π4π");
2157
+ cy.get(cesc("#\\/ypi")).should("contain.text", "−π−2π");
2158
+ cy.get(cesc("#\\/ypi")).should("contain.text", "−3π−4π");
2159
+ cy.get(cesc("#\\/ypi")).should("contain.text", "10");
2160
+ cy.get(cesc("#\\/ypi")).should("contain.text", "−10");
2161
+
2162
+ cy.get(cesc("#\\/bothpi")).should("contain.text", "π2π3π4π");
2163
+ cy.get(cesc("#\\/bothpi")).should("contain.text", "−π−2π");
2164
+ cy.get(cesc("#\\/bothpi")).should("contain.text", "−3π−4π");
2165
+ cy.get(cesc("#\\/bothpi")).should("not.contain.text", "10");
2166
+ cy.get(cesc("#\\/bothpi")).should("not.contain.text", "−10");
2167
+
2168
+ cy.get(cesc("#\\/xe")).should("contain.text", "e2e3e4e5e");
2169
+ cy.get(cesc("#\\/xe")).should("contain.text", "−e");
2170
+ cy.get(cesc("#\\/xe")).should("contain.text", "−2e−3e");
2171
+ cy.get(cesc("#\\/xe")).should("contain.text", "−4e−5e");
2172
+ cy.get(cesc("#\\/xe")).should("contain.text", "10");
2173
+ cy.get(cesc("#\\/xe")).should("contain.text", "−10");
2174
+
2175
+ cy.get(cesc("#\\/ye")).should("contain.text", "e2e3e4e5e");
2176
+ cy.get(cesc("#\\/ye")).should("contain.text", "−e");
2177
+ cy.get(cesc("#\\/ye")).should("contain.text", "−2e−3e");
2178
+ cy.get(cesc("#\\/ye")).should("contain.text", "−4e−5e");
2179
+ cy.get(cesc("#\\/ye")).should("contain.text", "10");
2180
+ cy.get(cesc("#\\/ye")).should("contain.text", "−10");
2181
+
2182
+ cy.get(cesc("#\\/bothe")).should("contain.text", "e2e3e4e5e");
2183
+ cy.get(cesc("#\\/bothe")).should("contain.text", "−e−2e");
2184
+ cy.get(cesc("#\\/bothe")).should("contain.text", "−3e−4e−5e");
2185
+ cy.get(cesc("#\\/bothe")).should("not.contain.text", "10");
2186
+ cy.get(cesc("#\\/bothe")).should("not.contain.text", "−10");
2187
+
2188
+ cy.get(cesc("#\\/ignorebad")).should("not.contain.text", "π");
2189
+ cy.get(cesc("#\\/ignorebad")).should("not.contain.text", "e");
2190
+ cy.get(cesc("#\\/ignorebad")).should("contain.text", "10");
2191
+ cy.get(cesc("#\\/ignorebad")).should("contain.text", "−10");
2192
+ });
2193
+
2194
+ it("display axes", () => {
2195
+ cy.window().then(async (win) => {
2196
+ win.postMessage(
2197
+ {
2198
+ doenetML: `
2199
+ <text>a</text>
2200
+
2201
+ <graph displayXAxis="$b1" displayYAxis="$b2">
2202
+ </graph>
2203
+ <booleaninput name="b1" />
2204
+ <copy prop="displayXAxis" target="_graph1" assignNames="b1a" />
2205
+ <booleaninput name="b2" prefill="true" />
2206
+ <copy prop="displayYAxis" target="_graph1" assignNames="b2a" />
2207
+
2208
+
2209
+ `,
2210
+ },
2211
+ "*",
2212
+ );
2213
+ });
2214
+
2215
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
2216
+
2217
+ // not sure what to test as don't know how to check renderer...
2218
+ cy.get(cesc("#\\/b1a")).should("have.text", "false");
2219
+ cy.get(cesc("#\\/b2a")).should("have.text", "true");
2220
+ cy.window().then(async (win) => {
2221
+ let stateVariables = await win.returnAllStateVariables1();
2222
+ expect(stateVariables["/_graph1"].stateValues.displayXAxis).eq(false);
2223
+ expect(stateVariables["/_graph1"].stateValues.displayYAxis).eq(true);
2224
+ });
2225
+
2226
+ cy.get(cesc("#\\/b1")).click();
2227
+
2228
+ cy.get(cesc("#\\/b1a")).should("have.text", "true");
2229
+ cy.get(cesc("#\\/b2a")).should("have.text", "true");
2230
+ cy.window().then(async (win) => {
2231
+ let stateVariables = await win.returnAllStateVariables1();
2232
+ expect(stateVariables["/_graph1"].stateValues.displayXAxis).eq(true);
2233
+ expect(stateVariables["/_graph1"].stateValues.displayYAxis).eq(true);
2234
+ });
2235
+
2236
+ cy.get(cesc("#\\/b2")).click();
2237
+
2238
+ cy.get(cesc("#\\/b1a")).should("have.text", "true");
2239
+ cy.get(cesc("#\\/b2a")).should("have.text", "false");
2240
+ cy.window().then(async (win) => {
2241
+ let stateVariables = await win.returnAllStateVariables1();
2242
+ expect(stateVariables["/_graph1"].stateValues.displayXAxis).eq(true);
2243
+ expect(stateVariables["/_graph1"].stateValues.displayYAxis).eq(false);
2244
+ });
2245
+
2246
+ cy.get(cesc("#\\/b1")).click();
2247
+
2248
+ cy.get(cesc("#\\/b1a")).should("have.text", "false");
2249
+ cy.get(cesc("#\\/b2a")).should("have.text", "false");
2250
+ cy.window().then(async (win) => {
2251
+ let stateVariables = await win.returnAllStateVariables1();
2252
+ expect(stateVariables["/_graph1"].stateValues.displayXAxis).eq(false);
2253
+ expect(stateVariables["/_graph1"].stateValues.displayYAxis).eq(false);
2254
+ });
2255
+
2256
+ cy.get(cesc("#\\/b2")).click();
2257
+
2258
+ cy.get(cesc("#\\/b1a")).should("have.text", "false");
2259
+ cy.get(cesc("#\\/b2a")).should("have.text", "true");
2260
+ cy.window().then(async (win) => {
2261
+ let stateVariables = await win.returnAllStateVariables1();
2262
+ expect(stateVariables["/_graph1"].stateValues.displayXAxis).eq(false);
2263
+ expect(stateVariables["/_graph1"].stateValues.displayYAxis).eq(true);
2264
+ });
2265
+ });
2266
+
2267
+ it("display navigation bar", () => {
2268
+ cy.window().then(async (win) => {
2269
+ win.postMessage(
2270
+ {
2271
+ doenetML: `
2272
+ <text>a</text>
2273
+
2274
+ <graph showNavigation="$b">
2275
+ </graph>
2276
+ <booleaninput name="b" />
2277
+ <copy prop="showNavigation" target="_graph1" assignNames="ba" />
2278
+
2279
+ `,
2280
+ },
2281
+ "*",
2282
+ );
2283
+ });
2284
+
2285
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
2286
+
2287
+ // not sure what to test as don't know how to check renderer...
2288
+ cy.get(cesc("#\\/ba")).should("have.text", "false");
2289
+ cy.window().then(async (win) => {
2290
+ let stateVariables = await win.returnAllStateVariables1();
2291
+ expect(stateVariables["/_graph1"].stateValues.showNavigation).eq(false);
2292
+ });
2293
+
2294
+ cy.get(cesc("#\\/b")).click();
2295
+
2296
+ cy.get(cesc("#\\/ba")).should("have.text", "true");
2297
+ cy.window().then(async (win) => {
2298
+ let stateVariables = await win.returnAllStateVariables1();
2299
+ expect(stateVariables["/_graph1"].stateValues.showNavigation).eq(true);
2300
+ });
2301
+
2302
+ cy.get(cesc("#\\/b")).click();
2303
+
2304
+ cy.get(cesc("#\\/ba")).should("have.text", "false");
2305
+ cy.window().then(async (win) => {
2306
+ let stateVariables = await win.returnAllStateVariables1();
2307
+ expect(stateVariables["/_graph1"].stateValues.showNavigation).eq(false);
2308
+ });
2309
+ });
2310
+
2311
+ it("display digits and decimals, overwrite in copies", () => {
2312
+ cy.window().then(async (win) => {
2313
+ win.postMessage(
2314
+ {
2315
+ doenetML: `
2316
+ <text>a</text>
2317
+
2318
+ <graph name="g" size="small" xmin="-45.03232523423" xmax="8.2857234234" ymin="-5.582342383823423" ymax="7.83710375032" />
2319
+ <graph name="gdg3" displayDigits="5" copySource="g" />
2320
+ <graph name="gdc5" displayDecimals="5" copySource="g" />
2321
+ <graph name="gdg3a" displayDigits="5" ignoreDisplayDecimals copySource="gdc5" />
2322
+ <graph name="gdc5a" displayDecimals="5" ignoreDisplayDigits copySource="gdg3" />
2323
+ <graph name="gdg3b" displayDigits="5" ignoreDisplayDecimals copySource="gdc5a" />
2324
+ <graph name="gdc5b" displayDecimals="5" ignoreDisplayDigits copySource="gdg3a" />
2325
+
2326
+ <p name="p">$g.xmin, $g.xmax, $g.ymin, $g.ymax</p>
2327
+
2328
+ <p name="pdg3">$gdg3.xmin, $gdg3.xmax, $gdg3.ymin, $gdg3.ymax</p>
2329
+ <p name="pdg3a">$gdg3a.xmin, $gdg3a.xmax, $gdg3a.ymin, $gdg3a.ymax</p>
2330
+ <p name="pdg3b">$gdg3b.xmin, $gdg3b.xmax, $gdg3b.ymin, $gdg3b.ymax</p>
2331
+ <p name="pdg3c">$g{displayDigits="5" ignoreDisplayDecimals}.xmin, $g{displayDigits="5" ignoreDisplayDecimals}.xmax, $g{displayDigits="5" ignoreDisplayDecimals}.ymin, $g{displayDigits="5" ignoreDisplayDecimals}.ymax</p>
2332
+ <p name="pdg3d">$gdc5{displayDigits="5" ignoreDisplayDecimals}.xmin, $gdc5{displayDigits="5" ignoreDisplayDecimals}.xmax, $gdc5{displayDigits="5" ignoreDisplayDecimals}.ymin, $gdc5{displayDigits="5" ignoreDisplayDecimals}.ymax</p>
2333
+
2334
+ <p name="pdc5">$gdc5.xmin, $gdc5.xmax, $gdc5.ymin, $gdc5.ymax</p>
2335
+ <p name="pdc5a">$gdc5a.xmin, $gdc5a.xmax, $gdc5a.ymin, $gdc5a.ymax</p>
2336
+ <p name="pdc5b">$gdc5b.xmin, $gdc5b.xmax, $gdc5b.ymin, $gdc5b.ymax</p>
2337
+ <p name="pdc5c">$g{displayDecimals="5" ignoreDisplayDigits}.xmin, $g{displayDecimals="5" ignoreDisplayDigits}.xmax, $g{displayDecimals="5" ignoreDisplayDigits}.ymin, $g{displayDecimals="5" ignoreDisplayDigits}.ymax</p>
2338
+ <p name="pdc5d">$gdg3{displayDecimals="5" ignoreDisplayDigits}.xmin, $gdg3{displayDecimals="5" ignoreDisplayDigits}.xmax, $gdg3{displayDecimals="5" ignoreDisplayDigits}.ymin, $gdg3{displayDecimals="5" ignoreDisplayDigits}.ymax</p>
2339
+
2340
+ `,
2341
+ },
2342
+ "*",
2343
+ );
2344
+ });
2345
+
2346
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
2347
+
2348
+ cy.get(cesc("#\\/p")).should("have.text", "-45.03, 8.29, -5.58, 7.84");
2349
+ cy.get(cesc("#\\/pdg3")).should(
2350
+ "have.text",
2351
+ "-45.032, 8.2857, -5.5823, 7.8371",
2352
+ );
2353
+ cy.get(cesc("#\\/pdg3b")).should(
2354
+ "have.text",
2355
+ "-45.032, 8.2857, -5.5823, 7.8371",
2356
+ );
2357
+ cy.get(cesc("#\\/pdg3c")).should(
2358
+ "have.text",
2359
+ "-45.032, 8.2857, -5.5823, 7.8371",
2360
+ );
2361
+ cy.get(cesc("#\\/pdg3d")).should(
2362
+ "have.text",
2363
+ "-45.032, 8.2857, -5.5823, 7.8371",
2364
+ );
2365
+ cy.get(cesc("#\\/pdc5")).should(
2366
+ "have.text",
2367
+ "-45.03233, 8.28572, -5.58234, 7.8371",
2368
+ );
2369
+ cy.get(cesc("#\\/pdc5b")).should(
2370
+ "have.text",
2371
+ "-45.03233, 8.28572, -5.58234, 7.8371",
2372
+ );
2373
+ cy.get(cesc("#\\/pdc5c")).should(
2374
+ "have.text",
2375
+ "-45.03233, 8.28572, -5.58234, 7.8371",
2376
+ );
2377
+ cy.get(cesc("#\\/pdc5d")).should(
2378
+ "have.text",
2379
+ "-45.03233, 8.28572, -5.58234, 7.8371",
2380
+ );
2381
+ });
2382
+
2383
+ it("pegboard", () => {
2384
+ cy.window().then(async (win) => {
2385
+ win.postMessage(
2386
+ {
2387
+ doenetML: `
2388
+ <text>a</text>
2389
+
2390
+ <graph>
2391
+ <pegboard />
2392
+ </graph>
2393
+
2394
+ <graph>
2395
+ <pegboard dx="3" dy="2" xoffset="1" yoffset="-1" />
2396
+ </graph>
2397
+ `,
2398
+ },
2399
+ "*",
2400
+ );
2401
+ });
2402
+
2403
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
2404
+
2405
+ // not sure what to test as don't know how to check renderer...
2406
+ cy.window().then(async (win) => {
2407
+ let stateVariables = await win.returnAllStateVariables1();
2408
+ expect(stateVariables["/_pegboard1"].stateValues.dx).eq(1);
2409
+ expect(stateVariables["/_pegboard1"].stateValues.dy).eq(1);
2410
+ expect(stateVariables["/_pegboard1"].stateValues.xoffset).eq(0);
2411
+ expect(stateVariables["/_pegboard1"].stateValues.yoffset).eq(0);
2412
+ expect(stateVariables["/_pegboard2"].stateValues.dx).eq(3);
2413
+ expect(stateVariables["/_pegboard2"].stateValues.dy).eq(2);
2414
+ expect(stateVariables["/_pegboard2"].stateValues.xoffset).eq(1);
2415
+ expect(stateVariables["/_pegboard2"].stateValues.yoffset).eq(-1);
2416
+ });
2417
+ });
2418
+
2419
+ it("show border", () => {
2420
+ cy.window().then(async (win) => {
2421
+ win.postMessage(
2422
+ {
2423
+ doenetML: `
2424
+ <text>a</text>
2425
+
2426
+ <graph>
2427
+ </graph>
2428
+
2429
+ <graph showBorder>
2430
+ </graph>
2431
+
2432
+ <graph showBorder="false">
2433
+ </graph>
2434
+ `,
2435
+ },
2436
+ "*",
2437
+ );
2438
+ });
2439
+
2440
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
2441
+
2442
+ // not sure what to test as don't know how to check renderer...
2443
+ cy.window().then(async (win) => {
2444
+ let stateVariables = await win.returnAllStateVariables1();
2445
+ expect(stateVariables["/_graph1"].stateValues.showBorder).eq(true);
2446
+ expect(stateVariables["/_graph2"].stateValues.showBorder).eq(true);
2447
+ expect(stateVariables["/_graph3"].stateValues.showBorder).eq(false);
2448
+ });
2449
+ });
2450
+
2451
+ it("graph inside graph renders children in parent graph", () => {
2452
+ cy.window().then(async (win) => {
2453
+ win.postMessage(
2454
+ {
2455
+ doenetML: `
2456
+ <text>a</text>
2457
+ <graph name="g1">
2458
+ <vector tail="(3,4)">(4,-5)</vector>
2459
+ <graph name="g1inner" xmin="-2" xmax="5" ymin="-3" ymax="4">
2460
+ <point>(6,9)
2461
+ <constraints>
2462
+ <constrainToGraph />
2463
+ </constraints>
2464
+ </point>
2465
+ </graph
2466
+ </graph>
2467
+
2468
+ <graph xmin="-15" xmax="15" ymin="-15" ymax="15" name="g2">
2469
+ <circle center="(-5,-4)" />
2470
+ $g1
2471
+ </graph>
2472
+
2473
+ `,
2474
+ },
2475
+ "*",
2476
+ );
2477
+
2478
+ cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load
2479
+
2480
+ // Not sure what to test as the interesting part is the graph renderer
2481
+ // The only new part from core is that the inner graph ignores its xmin, etc. attributes
2482
+ cy.window().then(async (win) => {
2483
+ let stateVariables = await win.returnAllStateVariables1();
2484
+ expect(stateVariables["/g1inner"].stateValues.xmin).eq(-10);
2485
+ expect(stateVariables["/g1inner"].stateValues.xmax).eq(10);
2486
+ expect(stateVariables["/g1inner"].stateValues.ymin).eq(-10);
2487
+ expect(stateVariables["/g1inner"].stateValues.ymax).eq(10);
2488
+ });
2489
+ });
2490
+ });
2491
+ });