kokopu-react 3.1.0 → 3.2.0

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 (234) hide show
  1. package/.eslintrc.yml +1 -1
  2. package/CHANGELOG.md +6 -0
  3. package/dist/lib/chessboard/BoardProperties.js.map +1 -1
  4. package/dist/lib/chessboard/Chessboard.css +13 -13
  5. package/dist/lib/chessboard/Chessboard.js.map +1 -1
  6. package/dist/lib/chessboard/ChessboardImpl.js.map +1 -1
  7. package/dist/lib/chessboard/Draggable.js.map +1 -1
  8. package/dist/lib/chessboard/Motion.js.map +1 -1
  9. package/dist/lib/chessboard/colorsets.js.map +1 -1
  10. package/dist/lib/chessboard/piecesets.js.map +1 -1
  11. package/dist/lib/errorbox/ErrorBox.css +18 -18
  12. package/dist/lib/errorbox/ErrorBox.js.map +1 -1
  13. package/dist/lib/errorbox/parsing.js.map +1 -1
  14. package/dist/lib/exception.js.map +1 -1
  15. package/dist/lib/i18n.d.ts +1 -0
  16. package/dist/lib/i18n.js +1 -0
  17. package/dist/lib/i18n.js.map +1 -1
  18. package/dist/lib/icons/AnnotationSymbolShape.css +6 -6
  19. package/dist/lib/icons/AnnotationSymbolShape.js.map +1 -1
  20. package/dist/lib/icons/ArrowMarkerIcon.js.map +1 -1
  21. package/dist/lib/icons/ArrowTip.js.map +1 -1
  22. package/dist/lib/icons/ChessPieceIcon.js.map +1 -1
  23. package/dist/lib/icons/SquareMarkerIcon.js.map +1 -1
  24. package/dist/lib/icons/TextMarkerIcon.js.map +1 -1
  25. package/dist/lib/icons/arrow.css +1 -1
  26. package/dist/lib/index.d.ts +1 -0
  27. package/dist/lib/index.js +1 -0
  28. package/dist/lib/index.js.map +1 -1
  29. package/dist/lib/movetext/Movetext.css +27 -27
  30. package/dist/lib/movetext/Movetext.js.map +1 -1
  31. package/dist/lib/movetext/MovetextImpl.js.map +1 -1
  32. package/dist/lib/movetext/fonts.css +7 -7
  33. package/dist/lib/movetext/htmlFilter.js.map +1 -1
  34. package/dist/lib/movetext/moveFormatter.js.map +1 -1
  35. package/dist/lib/navigationboard/NavigationBoard.d.ts +39 -1
  36. package/dist/lib/navigationboard/NavigationBoard.js +94 -11
  37. package/dist/lib/navigationboard/NavigationBoard.js.map +1 -1
  38. package/dist/lib/navigationboard/NavigationButton.d.ts +54 -0
  39. package/dist/lib/navigationboard/NavigationButton.js +35 -0
  40. package/dist/lib/navigationboard/NavigationButton.js.map +1 -0
  41. package/dist/lib/navigationboard/NavigationField.css +7 -7
  42. package/dist/lib/navigationboard/NavigationField.js.map +1 -1
  43. package/dist/lib/navigationboard/NavigationToolbar.css +16 -13
  44. package/dist/lib/navigationboard/NavigationToolbar.d.ts +3 -10
  45. package/dist/lib/navigationboard/NavigationToolbar.js +31 -82
  46. package/dist/lib/navigationboard/NavigationToolbar.js.map +1 -1
  47. package/dist/lib/navigationboard/iconPaths.d.ts +29 -0
  48. package/dist/lib/navigationboard/iconPaths.js +91 -0
  49. package/dist/lib/navigationboard/iconPaths.js.map +1 -0
  50. package/dist/lib/sanitization.js.map +1 -1
  51. package/dist/lib/types.js.map +1 -1
  52. package/dist/lib/util.js.map +1 -1
  53. package/doc_src/demo/PageChessboardBase.tsx +115 -115
  54. package/doc_src/demo/PageChessboardInteraction.tsx +303 -303
  55. package/doc_src/demo/PageChessboardMove.tsx +173 -173
  56. package/doc_src/demo/PageChessboardSmallScreens.tsx +94 -94
  57. package/doc_src/demo/PageMovetextBase.tsx +180 -180
  58. package/doc_src/demo/PageMovetextInteraction.tsx +123 -123
  59. package/doc_src/demo/PageNavigationBoardBase.tsx +144 -137
  60. package/doc_src/demo/PageNavigationBoardUncontrolledVsControlled.tsx +69 -69
  61. package/doc_src/demo/decs.d.ts +4 -4
  62. package/doc_src/demo/demo.css +12 -12
  63. package/doc_src/demo/util.ts +1 -1
  64. package/doc_src/examples/NavigationBoard.md +1 -1
  65. package/doc_src/theming/LogoRenderer.js +13 -13
  66. package/doc_src/theming/theming.css +5 -5
  67. package/package.json +95 -95
  68. package/scripts/doc.styleguide.config.js +131 -131
  69. package/scripts/doc.tsconfig.json +5 -5
  70. package/scripts/docker-compose.yml +1 -1
  71. package/scripts/test-graphic.tsconfig.json +5 -5
  72. package/scripts/test-graphic.webpack.config.js +57 -57
  73. package/scripts/test-headless.webpack.config.js +29 -29
  74. package/src/chessboard/BoardProperties.ts +68 -68
  75. package/src/chessboard/Chessboard.css +13 -13
  76. package/src/chessboard/Chessboard.tsx +380 -380
  77. package/src/chessboard/ChessboardImpl.tsx +557 -557
  78. package/src/chessboard/Draggable.tsx +185 -185
  79. package/src/chessboard/Motion.tsx +67 -67
  80. package/src/chessboard/colorsets.ts +66 -66
  81. package/src/chessboard/piecesets.ts +84 -84
  82. package/src/decs.d.ts +2 -2
  83. package/src/errorbox/ErrorBox.css +18 -18
  84. package/src/errorbox/ErrorBox.tsx +75 -75
  85. package/src/errorbox/parsing.tsx +95 -95
  86. package/src/exception.ts +17 -17
  87. package/src/i18n.ts +1 -0
  88. package/src/icons/AnnotationSymbolShape.css +6 -6
  89. package/src/icons/AnnotationSymbolShape.tsx +31 -31
  90. package/src/icons/ArrowMarkerIcon.tsx +34 -34
  91. package/src/icons/ArrowTip.tsx +14 -14
  92. package/src/icons/ChessPieceIcon.tsx +45 -45
  93. package/src/icons/SquareMarkerIcon.tsx +20 -20
  94. package/src/icons/TextMarkerIcon.tsx +29 -29
  95. package/src/icons/arrow.css +1 -1
  96. package/src/index.ts +3 -2
  97. package/src/movetext/Movetext.css +27 -27
  98. package/src/movetext/Movetext.tsx +158 -158
  99. package/src/movetext/MovetextImpl.tsx +345 -345
  100. package/src/movetext/fonts.css +7 -7
  101. package/src/movetext/htmlFilter.tsx +129 -129
  102. package/src/movetext/moveFormatter.tsx +37 -37
  103. package/src/navigationboard/NavigationBoard.tsx +297 -178
  104. package/src/navigationboard/NavigationButton.ts +72 -0
  105. package/src/navigationboard/NavigationField.css +7 -7
  106. package/src/navigationboard/NavigationField.tsx +90 -90
  107. package/src/navigationboard/NavigationToolbar.css +16 -13
  108. package/src/navigationboard/NavigationToolbar.tsx +60 -117
  109. package/src/navigationboard/iconPaths.ts +98 -0
  110. package/src/sanitization.ts +17 -17
  111. package/src/types.ts +116 -116
  112. package/src/util.ts +11 -11
  113. package/test/01_types.js +167 -167
  114. package/test/02_chessboard_util.js +114 -114
  115. package/test/03_error_box_graphic.js +16 -16
  116. package/test/04_icons_graphic.js +32 -32
  117. package/test/05_chessboard_graphic.js +60 -60
  118. package/test/06_chessboard_animation.js +36 -36
  119. package/test/07_chessboard_interaction.js +101 -101
  120. package/test/08_chessboard_play_moves.js +62 -62
  121. package/test/09_chessboard_small_screens.js +32 -32
  122. package/test/10_movetext_graphic.js +32 -32
  123. package/test/11_movetext_interaction.js +100 -100
  124. package/test/12_navigation_board_base.js +151 -0
  125. package/test/13_navigation_board_graphic.js +68 -0
  126. package/test/14_navigation_board_autoplay.js +100 -0
  127. package/test/common/graphic.js +106 -97
  128. package/test/graphic_references/12_navigation_board_base/controlled/default.png +0 -0
  129. package/test/graphic_references/{12_navigation_board/controlled/forbidden_navigation_1.png → 12_navigation_board_base/controlled/forbidden_navigation_0.png} +0 -0
  130. package/test/graphic_references/{12_navigation_board/controlled/invalid_node_id.png → 12_navigation_board_base/controlled/forbidden_navigation_1.png} +0 -0
  131. package/test/graphic_references/{12_navigation_board/controlled/forbidden_navigation_0.png → 12_navigation_board_base/controlled/invalid_node_id.png} +0 -0
  132. package/test/graphic_references/12_navigation_board_base/controlled/no_callback_defined_0.png +0 -0
  133. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/controlled/no_callback_defined_1.png +0 -0
  134. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/controlled/overriding_initial_node_id.png +0 -0
  135. package/test/graphic_references/{12_navigation_board/controlled/regular_navigation_1.png → 12_navigation_board_base/controlled/regular_navigation_0.png} +0 -0
  136. package/test/graphic_references/{12_navigation_board/uncontrolled/initial_state_at_specific_id.png → 12_navigation_board_base/controlled/regular_navigation_1.png} +0 -0
  137. package/test/graphic_references/{12_navigation_board/controlled/regular_navigation_3.png → 12_navigation_board_base/controlled/regular_navigation_2.png} +0 -0
  138. package/test/graphic_references/{12_navigation_board/controlled/regular_navigation_0.png → 12_navigation_board_base/controlled/regular_navigation_3.png} +0 -0
  139. package/test/graphic_references/{12_navigation_board/uncontrolled/forbidden_navigation_at_beginning_2.png → 12_navigation_board_base/uncontrolled/forbidden_navigation_at_beginning_0.png} +0 -0
  140. package/test/graphic_references/{12_navigation_board/uncontrolled/forbidden_navigation_at_beginning_0.png → 12_navigation_board_base/uncontrolled/forbidden_navigation_at_beginning_1.png} +0 -0
  141. package/test/graphic_references/{12_navigation_board/uncontrolled/forbidden_navigation_at_beginning_1.png → 12_navigation_board_base/uncontrolled/forbidden_navigation_at_beginning_2.png} +0 -0
  142. package/test/graphic_references/{12_navigation_board/controlled/no_callback_defined_0.png → 12_navigation_board_base/uncontrolled/forbidden_navigation_at_end_0.png} +0 -0
  143. package/test/graphic_references/12_navigation_board_base/uncontrolled/forbidden_navigation_at_end_1.png +0 -0
  144. package/test/graphic_references/12_navigation_board_base/uncontrolled/forbidden_navigation_at_end_2.png +0 -0
  145. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/initial_state_at_end.png +0 -0
  146. package/test/graphic_references/12_navigation_board_base/uncontrolled/initial_state_at_specific_id.png +0 -0
  147. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/initial_state_default.png +0 -0
  148. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/initial_state_default_with_game_index.png +0 -0
  149. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/initial_state_on_null-move.png +0 -0
  150. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/navigation_with_keys_0.png +0 -0
  151. package/test/graphic_references/12_navigation_board_base/uncontrolled/navigation_with_keys_1.png +0 -0
  152. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/navigation_with_keys_2.png +0 -0
  153. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/navigation_with_keys_3.png +0 -0
  154. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/navigation_with_keys_4.png +0 -0
  155. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/regular_flipping_0.png +0 -0
  156. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/regular_flipping_1.png +0 -0
  157. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/regular_navigation_0.png +0 -0
  158. package/test/graphic_references/{12_navigation_board/controlled/default.png → 12_navigation_board_base/uncontrolled/regular_navigation_1.png} +0 -0
  159. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/regular_navigation_2.png +0 -0
  160. package/test/graphic_references/12_navigation_board_base/uncontrolled/regular_navigation_3.png +0 -0
  161. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/regular_navigation_4.png +0 -0
  162. package/test/graphic_references/{12_navigation_board → 12_navigation_board_base}/uncontrolled/regular_navigation_5.png +0 -0
  163. package/test/graphic_references/13_navigation_board_graphic/additional_buttons/error_1.png +0 -0
  164. package/test/graphic_references/13_navigation_board_graphic/additional_buttons/error_2.png +0 -0
  165. package/test/graphic_references/13_navigation_board_graphic/additional_buttons/multiple_buttons.png +0 -0
  166. package/test/graphic_references/{12_navigation_board/uncontrolled/regular_navigation_3.png → 13_navigation_board_graphic/additional_buttons/single_button.png} +0 -0
  167. package/test/graphic_references/{12_navigation_board → 13_navigation_board_graphic}/theme/custom_1.png +0 -0
  168. package/test/graphic_references/{12_navigation_board → 13_navigation_board_graphic}/theme/custom_2.png +0 -0
  169. package/test/graphic_references/{12_navigation_board → 13_navigation_board_graphic}/theme/large.png +0 -0
  170. package/test/graphic_references/13_navigation_board_graphic/theme/small.png +0 -0
  171. package/test/graphic_references/14_navigation_board_autoplay/controlled/after_1_move_acknowledging_is-playing_changes.png +0 -0
  172. package/test/graphic_references/14_navigation_board_autoplay/controlled/after_1_move_not_acknowledging_is-playing_changes.png +0 -0
  173. package/test/graphic_references/14_navigation_board_autoplay/controlled/after_2_moves_acknowledging_node_changes.png +0 -0
  174. package/test/graphic_references/14_navigation_board_autoplay/controlled/after_2_moves_not_acknowledging_node_changes.png +0 -0
  175. package/test/graphic_references/{12_navigation_board/uncontrolled/forbidden_navigation_at_end_1.png → 14_navigation_board_autoplay/controlled/after_reaching_the_end.png} +0 -0
  176. package/test/graphic_references/{12_navigation_board/uncontrolled/forbidden_navigation_at_end_2.png → 14_navigation_board_autoplay/controlled/already_at_the_end.png} +0 -0
  177. package/test/graphic_references/14_navigation_board_autoplay/controlled/initial_state_acknowledging_is-playing_changes.png +0 -0
  178. package/test/graphic_references/14_navigation_board_autoplay/controlled/initial_state_acknowledging_node_changes.png +0 -0
  179. package/test/graphic_references/{12_navigation_board/uncontrolled/forbidden_navigation_at_end_0.png → 14_navigation_board_autoplay/controlled/initial_state_at_the_end.png} +0 -0
  180. package/test/graphic_references/14_navigation_board_autoplay/controlled/initial_state_close_to_end.png +0 -0
  181. package/test/graphic_references/14_navigation_board_autoplay/controlled/initial_state_not_acknowledging_is-playing_changes.png +0 -0
  182. package/test/graphic_references/14_navigation_board_autoplay/controlled/initial_state_not_acknowledging_node_changes.png +0 -0
  183. package/test/graphic_references/14_navigation_board_autoplay/uncontrolled/after_2_moves_from_beginning_after_stop.png +0 -0
  184. package/test/graphic_references/14_navigation_board_autoplay/uncontrolled/after_2_moves_from_beginning_before_stop.png +0 -0
  185. package/test/graphic_references/14_navigation_board_autoplay/uncontrolled/after_reaching_the_end_after_stop.png +0 -0
  186. package/test/graphic_references/14_navigation_board_autoplay/uncontrolled/after_reaching_the_end_before_stop.png +0 -0
  187. package/test/graphic_references/14_navigation_board_autoplay/uncontrolled/initial_state_close_to_end.png +0 -0
  188. package/test/graphic_references/{12_navigation_board/uncontrolled/navigation_with_keys_1.png → 14_navigation_board_autoplay/uncontrolled/initial_state_default.png} +0 -0
  189. package/test/graphic_test_app/03_error_box_graphic/base.tsx +14 -14
  190. package/test/graphic_test_app/03_error_box_graphic/localization.tsx +1 -1
  191. package/test/graphic_test_app/04_icons_graphic/chess_piece.tsx +7 -7
  192. package/test/graphic_test_app/04_icons_graphic/marker.tsx +15 -15
  193. package/test/graphic_test_app/05_chessboard_graphic/annotations.tsx +7 -7
  194. package/test/graphic_test_app/05_chessboard_graphic/base.tsx +6 -6
  195. package/test/graphic_test_app/05_chessboard_graphic/chess_variants.tsx +7 -7
  196. package/test/graphic_test_app/05_chessboard_graphic/flipped.tsx +5 -5
  197. package/test/graphic_test_app/05_chessboard_graphic/move.tsx +12 -12
  198. package/test/graphic_test_app/05_chessboard_graphic/theme.tsx +12 -12
  199. package/test/graphic_test_app/06_chessboard_animation/base_1.tsx +6 -6
  200. package/test/graphic_test_app/06_chessboard_animation/base_2.tsx +6 -6
  201. package/test/graphic_test_app/06_chessboard_animation/base_3.tsx +6 -6
  202. package/test/graphic_test_app/06_chessboard_animation/on_redraw.tsx +16 -16
  203. package/test/graphic_test_app/07_chessboard_interaction/click_squares.tsx +5 -5
  204. package/test/graphic_test_app/07_chessboard_interaction/edit_arrows.tsx +4 -4
  205. package/test/graphic_test_app/07_chessboard_interaction/error.tsx +2 -2
  206. package/test/graphic_test_app/07_chessboard_interaction/move_pieces.tsx +5 -5
  207. package/test/graphic_test_app/08_chessboard_play_moves/base.tsx +8 -8
  208. package/test/graphic_test_app/08_chessboard_play_moves/promotions.tsx +4 -4
  209. package/test/graphic_test_app/09_chessboard_small_screens/base.tsx +9 -9
  210. package/test/graphic_test_app/09_chessboard_small_screens/top_bottom_components.tsx +9 -9
  211. package/test/graphic_test_app/10_movetext_graphic/base.tsx +4 -4
  212. package/test/graphic_test_app/10_movetext_graphic/error.tsx +6 -6
  213. package/test/graphic_test_app/10_movetext_graphic/format_move.tsx +1 -1
  214. package/test/graphic_test_app/10_movetext_graphic/html.tsx +5 -5
  215. package/test/graphic_test_app/10_movetext_graphic/options.tsx +10 -10
  216. package/test/graphic_test_app/11_movetext_interaction/error.tsx +1 -1
  217. package/test/graphic_test_app/11_movetext_interaction/select_moves.tsx +11 -11
  218. package/test/graphic_test_app/{12_navigation_board → 12_navigation_board_base}/controlled.tsx +5 -5
  219. package/test/graphic_test_app/{12_navigation_board → 12_navigation_board_base}/uncontrolled.tsx +7 -7
  220. package/test/graphic_test_app/13_navigation_board_graphic/additional_buttons.tsx +49 -0
  221. package/test/graphic_test_app/{12_navigation_board → 13_navigation_board_graphic}/error.tsx +2 -2
  222. package/test/graphic_test_app/{12_navigation_board → 13_navigation_board_graphic}/theme.tsx +4 -4
  223. package/test/graphic_test_app/14_navigation_board_autoplay/controlled.tsx +73 -0
  224. package/test/graphic_test_app/14_navigation_board_autoplay/uncontrolled.tsx +34 -0
  225. package/test/graphic_test_app/common/decs.d.ts +2 -2
  226. package/test/graphic_test_app/common/test_app.css +15 -15
  227. package/test/graphic_test_app/common/test_app.tsx +48 -48
  228. package/tsconfig.json +13 -13
  229. package/test/12_navigation_board.js +0 -168
  230. package/test/graphic_references/12_navigation_board/controlled/regular_navigation_2.png +0 -0
  231. package/test/graphic_references/12_navigation_board/theme/small.png +0 -0
  232. package/test/graphic_references/12_navigation_board/uncontrolled/regular_navigation_1.png +0 -0
  233. /package/test/graphic_references/{12_navigation_board → 13_navigation_board_graphic}/error/pgn_parsing_error.png +0 -0
  234. /package/test/graphic_references/{12_navigation_board → 13_navigation_board_graphic}/error/wrong_game_type.png +0 -0
@@ -34,38 +34,39 @@ const outputDir = rootDir + '/build/graphic_output';
34
34
  const coverageDir = rootDir + '/build/.nyc_output';
35
35
 
36
36
  const UNREACHABLE_TEST_CLIENT_MESSAGE =
37
- 'Cannot reach the Dockerized Selenium webbrowser used for graphic tests (probably because the test environment is not running).\n' +
38
- '\n' +
39
- 'Use command `npm run test_env:start` to start the test environment.\n' +
40
- 'Do not forget to run `npm run test_env:stop` when finished.\n';
37
+ 'Cannot reach the Dockerized Selenium webbrowser used for graphic tests (probably because the test environment is not running).\n' +
38
+ '\n' +
39
+ 'Use command `npm run test_env:start` to start the test environment.\n' +
40
+ 'Do not forget to run `npm run test_env:stop` when finished.\n';
41
41
 
42
42
 
43
43
  const ANIMATION_DELAY = 200;
44
+ const AUTOPLAY_DELAY = 1000;
44
45
 
45
46
 
46
47
  /**
47
48
  * Create a Mocha test-suite that runs graphic tests in Dockerized Selenium webbrowser.
48
49
  */
49
50
  exports.describeWithBrowser = function(suiteLabel, testFactory) {
50
- describe(suiteLabel, function() {
51
+ describe(suiteLabel, function() {
51
52
 
52
- // Fetching a new page in the browser may take a while, thus increase the timeout threshold.
53
- this.timeout(10000);
53
+ // Fetching a new page in the browser may take a while, thus increase the timeout threshold.
54
+ this.timeout(10000);
54
55
 
55
- // Configure the browser context.
56
- const browserContext = {};
56
+ // Configure the browser context.
57
+ const browserContext = {};
57
58
 
58
- before(async () => {
59
- await openBrowser(browserContext);
60
- });
59
+ before(async () => {
60
+ await openBrowser(browserContext);
61
+ });
61
62
 
62
- after(async () => {
63
- await closeBrowser(browserContext);
64
- });
63
+ after(async () => {
64
+ await closeBrowser(browserContext);
65
+ });
65
66
 
66
- // Register the tests.
67
- testFactory(browserContext);
68
- });
67
+ // Register the tests.
68
+ testFactory(browserContext);
69
+ });
69
70
  };
70
71
 
71
72
 
@@ -74,15 +75,15 @@ exports.describeWithBrowser = function(suiteLabel, testFactory) {
74
75
  */
75
76
  async function openBrowser(browserContext) {
76
77
 
77
- // Start the browser and ensure it can fetch something.
78
- const capabilities = Capabilities.firefox();
79
- const driver = new Builder().usingServer('http://localhost:4444').withCapabilities(capabilities).build();
80
- await driver.get('file:///app/build/test_graphic/heartbeat.txt').catch(reason => {
81
- return Promise.reject(reason.message.includes('ECONNREFUSED') ? new Error(UNREACHABLE_TEST_CLIENT_MESSAGE) : reason);
82
- });
78
+ // Start the browser and ensure it can fetch something.
79
+ const capabilities = Capabilities.firefox();
80
+ const driver = new Builder().usingServer('http://localhost:4444').withCapabilities(capabilities).build();
81
+ await driver.get('file:///app/build/test_graphic/heartbeat.txt').catch(reason => {
82
+ return Promise.reject(reason.message.includes('ECONNREFUSED') ? new Error(UNREACHABLE_TEST_CLIENT_MESSAGE) : reason);
83
+ });
83
84
 
84
- // Initialize the browser context
85
- browserContext.driver = driver;
85
+ // Initialize the browser context
86
+ browserContext.driver = driver;
86
87
  }
87
88
 
88
89
 
@@ -90,16 +91,16 @@ async function openBrowser(browserContext) {
90
91
  * Close the given browser.
91
92
  */
92
93
  async function closeBrowser(browserContext) {
93
- if (browserContext.driver) {
94
+ if (browserContext.driver) {
94
95
 
95
- // Save the coverage data before closing the browser.
96
- await saveCoverage(browserContext);
96
+ // Save the coverage data before closing the browser.
97
+ await saveCoverage(browserContext);
97
98
 
98
- // Close the browser and clean its context.
99
- await browserContext.driver.quit();
100
- delete browserContext.driver;
101
- delete browserContext.latestTestCase;
102
- }
99
+ // Close the browser and clean its context.
100
+ await browserContext.driver.quit();
101
+ delete browserContext.driver;
102
+ delete browserContext.latestTestCase;
103
+ }
103
104
  }
104
105
 
105
106
 
@@ -107,21 +108,21 @@ async function closeBrowser(browserContext) {
107
108
  * Save the coverage data, if any.
108
109
  */
109
110
  async function saveCoverage(browserContext) {
110
- if (!browserContext.latestTestCase) {
111
- return;
112
- }
113
-
114
- // Allocate a filename to save the coverage data.
115
- let pageIndex = 0;
116
- let coverageFile = '';
117
- do {
118
- coverageFile = `${coverageDir}/${browserContext.latestTestCase.replaceAll('/', '__')}-${pageIndex}.json`;
119
- ++pageIndex;
120
- } while (fs.existsSync(coverageFile));
121
-
122
- // Retrieve and save the coverage data.
123
- const coverageData = await browserContext.driver.executeScript('return JSON.stringify(window.__coverage__)');
124
- fs.writeFileSync(coverageFile, coverageData);
111
+ if (!browserContext.latestTestCase) {
112
+ return;
113
+ }
114
+
115
+ // Allocate a filename to save the coverage data.
116
+ let pageIndex = 0;
117
+ let coverageFile = '';
118
+ do {
119
+ coverageFile = `${coverageDir}/${browserContext.latestTestCase.replaceAll('/', '__')}-${pageIndex}.json`;
120
+ ++pageIndex;
121
+ } while (fs.existsSync(coverageFile));
122
+
123
+ // Retrieve and save the coverage data.
124
+ const coverageData = await browserContext.driver.executeScript('return JSON.stringify(window.__coverage__)');
125
+ fs.writeFileSync(coverageFile, coverageData);
125
126
  }
126
127
 
127
128
 
@@ -129,17 +130,17 @@ async function saveCoverage(browserContext) {
129
130
  * Open the page corresponding to the given test-case.
130
131
  */
131
132
  async function fetchTestCase(browserContext, testCaseName) {
132
- if (browserContext.latestTestCase === testCaseName) {
133
- return;
134
- }
133
+ if (browserContext.latestTestCase === testCaseName) {
134
+ return;
135
+ }
135
136
 
136
- // Save coverage data before changing the page.
137
- await saveCoverage(browserContext);
137
+ // Save coverage data before changing the page.
138
+ await saveCoverage(browserContext);
138
139
 
139
- // Fetch the new page.
140
- await browserContext.driver.get(`file:///app/build/test_graphic/${testCaseName}/index.html`);
141
- browserContext.latestTestCase = testCaseName;
142
- await waitForAnimation();
140
+ // Fetch the new page.
141
+ await browserContext.driver.get(`file:///app/build/test_graphic/${testCaseName}/index.html`);
142
+ browserContext.latestTestCase = testCaseName;
143
+ await waitForAnimation();
143
144
  }
144
145
 
145
146
 
@@ -147,7 +148,15 @@ async function fetchTestCase(browserContext, testCaseName) {
147
148
  * Wait until the end of the chessboard animations.
148
149
  */
149
150
  const waitForAnimation = exports.waitForAnimation = async function() {
150
- await new Promise(resolve => setTimeout(resolve, ANIMATION_DELAY));
151
+ await new Promise(resolve => setTimeout(resolve, ANIMATION_DELAY));
152
+ };
153
+
154
+
155
+ /**
156
+ * Wait until the given number of moves have been auto-played.
157
+ */
158
+ exports.waitForAutoplay = async function(nbMoves) {
159
+ await new Promise(resolve => setTimeout(resolve, (nbMoves + 0.5) * AUTOPLAY_DELAY));
151
160
  };
152
161
 
153
162
 
@@ -156,13 +165,13 @@ const waitForAnimation = exports.waitForAnimation = async function() {
156
165
  */
157
166
  const takeScreenshot = exports.takeScreenshot = async function(browserContext, imageBaseName, element) {
158
167
 
159
- imageBaseName = imageBaseName.replaceAll(' ', '_').toLowerCase();
160
- const actualFilename = `${outputDir}/${browserContext.latestTestCase}/${imageBaseName}.png`;
168
+ imageBaseName = imageBaseName.replaceAll(' ', '_').toLowerCase();
169
+ const actualFilename = `${outputDir}/${browserContext.latestTestCase}/${imageBaseName}.png`;
161
170
 
162
- // Take a screenshot of the targeted element.
163
- const image = await element.takeScreenshot();
164
- fs.mkdirSync(path.dirname(actualFilename), { recursive: true });
165
- fs.writeFileSync(actualFilename, image, 'base64');
171
+ // Take a screenshot of the targeted element.
172
+ const image = await element.takeScreenshot();
173
+ fs.mkdirSync(path.dirname(actualFilename), { recursive: true });
174
+ fs.writeFileSync(actualFilename, image, 'base64');
166
175
  };
167
176
 
168
177
 
@@ -171,18 +180,18 @@ const takeScreenshot = exports.takeScreenshot = async function(browserContext, i
171
180
  */
172
181
  const compareScreenshot = exports.compareScreenshot = async function(browserContext, imageBaseName) {
173
182
 
174
- imageBaseName = imageBaseName.replaceAll(' ', '_').toLowerCase();
175
- const actualFilename = `${outputDir}/${browserContext.latestTestCase}/${imageBaseName}.png`;
176
- const expectedFilename = `${referenceDir}/${browserContext.latestTestCase}/${imageBaseName}.png`;
177
- const differenceFilename = `${outputDir}/${browserContext.latestTestCase}/${imageBaseName}.diff.png`;
178
-
179
- // Compare the current screenshot to the reference.
180
- const result = await imgDiff({
181
- actualFilename: actualFilename,
182
- expectedFilename: expectedFilename,
183
- diffFilename: differenceFilename,
184
- });
185
- test.object(result).hasProperty('imagesAreSame', true);
183
+ imageBaseName = imageBaseName.replaceAll(' ', '_').toLowerCase();
184
+ const actualFilename = `${outputDir}/${browserContext.latestTestCase}/${imageBaseName}.png`;
185
+ const expectedFilename = `${referenceDir}/${browserContext.latestTestCase}/${imageBaseName}.png`;
186
+ const differenceFilename = `${outputDir}/${browserContext.latestTestCase}/${imageBaseName}.diff.png`;
187
+
188
+ // Compare the current screenshot to the reference.
189
+ const result = await imgDiff({
190
+ actualFilename: actualFilename,
191
+ expectedFilename: expectedFilename,
192
+ diffFilename: differenceFilename,
193
+ });
194
+ test.object(result).hasProperty('imagesAreSame', true);
186
195
  };
187
196
 
188
197
 
@@ -190,8 +199,8 @@ const compareScreenshot = exports.compareScreenshot = async function(browserCont
190
199
  * Compare content of the sandbox to the expected text.
191
200
  */
192
201
  exports.compareSandbox = async function(browserContext, expectedText) {
193
- const actualText = await browserContext.driver.findElement(By.id('sandbox')).getText();
194
- test.value(actualText).is(expectedText);
202
+ const actualText = await browserContext.driver.findElement(By.id('sandbox')).getText();
203
+ test.value(actualText).is(expectedText);
195
204
  };
196
205
 
197
206
 
@@ -199,10 +208,10 @@ exports.compareSandbox = async function(browserContext, expectedText) {
199
208
  * Set the content of the sandbox to the given value.
200
209
  */
201
210
  exports.setSandbox = async function(browserContext, value) {
202
- if (/[^\w \-=]/.test(value)) {
203
- throw new Error('Invalid characters found in the sandox message.');
204
- }
205
- await browserContext.driver.executeScript(`document.getElementById("sandbox").innerText = "${value}"`);
211
+ if (/[^\w \-=]/.test(value)) {
212
+ throw new Error('Invalid characters found in the sandox message.');
213
+ }
214
+ await browserContext.driver.executeScript(`document.getElementById("sandbox").innerText = "${value}"`);
206
215
  };
207
216
 
208
217
 
@@ -210,8 +219,8 @@ exports.setSandbox = async function(browserContext, value) {
210
219
  * Set the width of the browser.
211
220
  */
212
221
  exports.setWindowWidth = async function(browserContext, width) {
213
- const { height } = await await browserContext.driver.manage().window().getRect();
214
- await browserContext.driver.manage().window().setRect({ width: width, height: height });
222
+ const { height } = await await browserContext.driver.manage().window().getRect();
223
+ await browserContext.driver.manage().window().setRect({ width: width, height: height });
215
224
  };
216
225
 
217
226
 
@@ -219,11 +228,11 @@ exports.setWindowWidth = async function(browserContext, width) {
219
228
  * Open the page corresponding to the given test-case, and execute the given scenario.
220
229
  */
221
230
  const itCustom = exports.itCustom = function(browserContext, testCaseName, itemIndex, itemName, scenario) {
222
- it(`${testCaseName} - ${itemName}`, async () => {
223
- await fetchTestCase(browserContext, testCaseName);
224
- const element = await browserContext.driver.findElement(By.id('test-item-' + itemIndex));
225
- await scenario(element);
226
- });
231
+ it(`${testCaseName} - ${itemName}`, async () => {
232
+ await fetchTestCase(browserContext, testCaseName);
233
+ const element = await browserContext.driver.findElement(By.id('test-item-' + itemIndex));
234
+ await scenario(element);
235
+ });
227
236
  };
228
237
 
229
238
 
@@ -231,11 +240,11 @@ const itCustom = exports.itCustom = function(browserContext, testCaseName, itemI
231
240
  * Open the page corresponding to the given test-case, take a screenshot for each item, and compare them to the reference.
232
241
  */
233
242
  exports.itChecksScreenshots = function(browserContext, testCaseName, itemNames) {
234
- for (let i = 0; i < itemNames.length; ++i) {
235
- const itemName = itemNames[i];
236
- itCustom(browserContext, testCaseName, i, itemName, async element => {
237
- await takeScreenshot(browserContext, itemName, element);
238
- await compareScreenshot(browserContext, itemName);
239
- });
240
- }
243
+ for (let i = 0; i < itemNames.length; ++i) {
244
+ const itemName = itemNames[i];
245
+ itCustom(browserContext, testCaseName, i, itemName, async element => {
246
+ await takeScreenshot(browserContext, itemName, element);
247
+ await compareScreenshot(browserContext, itemName);
248
+ });
249
+ }
241
250
  };
@@ -28,21 +28,21 @@ import { ErrorBox } from '../../../dist/lib/index';
28
28
 
29
29
  testApp([ /* eslint-disable react/jsx-key */
30
30
 
31
- <ErrorBox title="I'm the title" message="I'm the message" />,
32
- <ErrorBox title="The title" message="Keep both the beginning and the end" text="| Error: x <- is here" errorIndex={9} lineNumber={1} />,
31
+ <ErrorBox title="I'm the title" message="I'm the message" />,
32
+ <ErrorBox title="The title" message="Keep both the beginning and the end" text="| Error: x <- is here" errorIndex={9} lineNumber={1} />,
33
33
 
34
- <ErrorBox title="No error index" message="Nothing below" text="You will not see this..." />,
35
- <ErrorBox title="No error text" message="Nothing below" errorIndex={1} />,
36
- <ErrorBox title="Negative error index" message="Nothing below" text="You will not see this..." errorIndex={-1} />,
37
- <ErrorBox title="Too large error index" message="Nothing below" text="You will not see this..." errorIndex={100} />,
38
- <ErrorBox title="Error index not an integer" message="Nothing below" text="You will not see this..." errorIndex={2.3} />,
34
+ <ErrorBox title="No error index" message="Nothing below" text="You will not see this..." />,
35
+ <ErrorBox title="No error text" message="Nothing below" errorIndex={1} />,
36
+ <ErrorBox title="Negative error index" message="Nothing below" text="You will not see this..." errorIndex={-1} />,
37
+ <ErrorBox title="Too large error index" message="Nothing below" text="You will not see this..." errorIndex={100} />,
38
+ <ErrorBox title="Error index not an integer" message="Nothing below" text="You will not see this..." errorIndex={2.3} />,
39
39
 
40
- <ErrorBox title="Cut the end of the text" message="and keep all the beginning" text="| x <- the error is there and the rest of the line is cut because too long"
41
- errorIndex={2} />,
42
- <ErrorBox title="Cut the beginning of the text" message="and keep all the end" text="The error is there -> x 234567890 234567890 234567890 234567890"
43
- errorIndex={22} lineNumber={0} />,
44
- <ErrorBox title="Cut on line breaks" message="both at the beginning and at the end" text={'This is the first line\n| x |\nThis is the third line'}
45
- errorIndex={25} lineNumber={2} />,
46
- <ErrorBox title="Single character text" message="The text is 1-character long" text="x" errorIndex={0} lineNumber={1.1} />,
40
+ <ErrorBox title="Cut the end of the text" message="and keep all the beginning" text="| x <- the error is there and the rest of the line is cut because too long"
41
+ errorIndex={2} />,
42
+ <ErrorBox title="Cut the beginning of the text" message="and keep all the end" text="The error is there -> x 234567890 234567890 234567890 234567890"
43
+ errorIndex={22} lineNumber={0} />,
44
+ <ErrorBox title="Cut on line breaks" message="both at the beginning and at the end" text={'This is the first line\n| x |\nThis is the third line'}
45
+ errorIndex={25} lineNumber={2} />,
46
+ <ErrorBox title="Single character text" message="The text is 1-character long" text="x" errorIndex={0} lineNumber={1.1} />,
47
47
 
48
48
  ]); /* eslint-enable react/jsx-key */
@@ -30,5 +30,5 @@ import { ErrorBox, i18n } from '../../../dist/lib/index';
30
30
  i18n.LINE = 'ligne {0} (+ invalid placeholder {1})';
31
31
 
32
32
  testApp([ /* eslint-disable react/jsx-key */
33
- <ErrorBox title="The title" message="The message" text="| x <- error is here" errorIndex={2} lineNumber={42} />,
33
+ <ErrorBox title="The title" message="The message" text="| x <- error is here" errorIndex={2} lineNumber={42} />,
34
34
  ]); /* eslint-enable react/jsx-key */
@@ -28,13 +28,13 @@ import { ChessPieceIcon } from '../../../dist/lib/index';
28
28
 
29
29
  testApp([ /* eslint-disable react/jsx-key */
30
30
 
31
- <ChessPieceIcon size={44} type="wq" />,
32
- <ChessPieceIcon size={24} type={[ 'bb', 'wx', 'wx', 'wn', 'bx', 'bk', 'bk' ]} />,
33
- <ChessPieceIcon size={36} type={[ 'wr', 'wb', 'bq' ]} pieceset="eyes" />,
31
+ <ChessPieceIcon size={44} type="wq" />,
32
+ <ChessPieceIcon size={24} type={[ 'bb', 'wx', 'wx', 'wn', 'bx', 'bk', 'bk' ]} />,
33
+ <ChessPieceIcon size={36} type={[ 'wr', 'wb', 'bq' ]} pieceset="eyes" />,
34
34
 
35
- <ChessPieceIcon size={ /* eslint-disable @typescript-eslint/no-explicit-any */ 'not-a-number' as any /* eslint-enable @typescript-eslint/no-explicit-any */ } type="wq" />,
36
- <ChessPieceIcon size={40} type={ /* eslint-disable @typescript-eslint/no-explicit-any */ 'invalid' as any /* eslint-enable @typescript-eslint/no-explicit-any */ } />,
37
- <ChessPieceIcon size={40} type={[ 'bb', /* eslint-disable @typescript-eslint/no-explicit-any */ 'zp' as any /* eslint-enable @typescript-eslint/no-explicit-any */ ]} />,
38
- <ChessPieceIcon size={40} type="wq" pieceset="not-a-pieceset" />,
35
+ <ChessPieceIcon size={ /* eslint-disable @typescript-eslint/no-explicit-any */ 'not-a-number' as any /* eslint-enable @typescript-eslint/no-explicit-any */ } type="wq" />,
36
+ <ChessPieceIcon size={40} type={ /* eslint-disable @typescript-eslint/no-explicit-any */ 'invalid' as any /* eslint-enable @typescript-eslint/no-explicit-any */ } />,
37
+ <ChessPieceIcon size={40} type={[ 'bb', /* eslint-disable @typescript-eslint/no-explicit-any */ 'zp' as any /* eslint-enable @typescript-eslint/no-explicit-any */ ]} />,
38
+ <ChessPieceIcon size={40} type="wq" pieceset="not-a-pieceset" />,
39
39
 
40
40
  ]); /* eslint-enable react/jsx-key */
@@ -28,22 +28,22 @@ import { SquareMarkerIcon, TextMarkerIcon, ArrowMarkerIcon } from '../../../dist
28
28
 
29
29
  testApp([ /* eslint-disable react/jsx-key */
30
30
 
31
- <SquareMarkerIcon size={40} />,
32
- <SquareMarkerIcon size={45} color="green" />,
33
- <div style={{ color: 'purple' }}><SquareMarkerIcon size={31} /></div>,
34
- <SquareMarkerIcon size={ /* eslint-disable @typescript-eslint/no-explicit-any */ 'not-a-number' as any /* eslint-enable @typescript-eslint/no-explicit-any */ } />,
31
+ <SquareMarkerIcon size={40} />,
32
+ <SquareMarkerIcon size={45} color="green" />,
33
+ <div style={{ color: 'purple' }}><SquareMarkerIcon size={31} /></div>,
34
+ <SquareMarkerIcon size={ /* eslint-disable @typescript-eslint/no-explicit-any */ 'not-a-number' as any /* eslint-enable @typescript-eslint/no-explicit-any */ } />,
35
35
 
36
- <TextMarkerIcon size={41} symbol="A" />,
37
- <TextMarkerIcon size={29} symbol="b" color="#0ff" />,
38
- <div style={{ color: 'red' }}><TextMarkerIcon size={53} symbol="5" /></div>,
39
- <TextMarkerIcon size={47} symbol="dot" color="#00f" />,
40
- <div style={{ color: 'pink' }}><TextMarkerIcon size={48} symbol="circle" /></div>,
41
- <TextMarkerIcon size={ /* eslint-disable @typescript-eslint/no-explicit-any */ 'not-a-number' as any /* eslint-enable @typescript-eslint/no-explicit-any */ } symbol="A" />,
42
- <TextMarkerIcon size={40} symbol={ /* eslint-disable @typescript-eslint/no-explicit-any */ 'not-a-symbol' as any /* eslint-enable @typescript-eslint/no-explicit-any */ } />,
36
+ <TextMarkerIcon size={41} symbol="A" />,
37
+ <TextMarkerIcon size={29} symbol="b" color="#0ff" />,
38
+ <div style={{ color: 'red' }}><TextMarkerIcon size={53} symbol="5" /></div>,
39
+ <TextMarkerIcon size={47} symbol="dot" color="#00f" />,
40
+ <div style={{ color: 'pink' }}><TextMarkerIcon size={48} symbol="circle" /></div>,
41
+ <TextMarkerIcon size={ /* eslint-disable @typescript-eslint/no-explicit-any */ 'not-a-number' as any /* eslint-enable @typescript-eslint/no-explicit-any */ } symbol="A" />,
42
+ <TextMarkerIcon size={40} symbol={ /* eslint-disable @typescript-eslint/no-explicit-any */ 'not-a-symbol' as any /* eslint-enable @typescript-eslint/no-explicit-any */ } />,
43
43
 
44
- <ArrowMarkerIcon size={40} />,
45
- <ArrowMarkerIcon size={24} color="#888" />,
46
- <div style={{ color: '#f70' }}><ArrowMarkerIcon size={48} /></div>,
47
- <ArrowMarkerIcon size={ /* eslint-disable @typescript-eslint/no-explicit-any */ 'not-a-number' as any /* eslint-enable @typescript-eslint/no-explicit-any */ } />,
44
+ <ArrowMarkerIcon size={40} />,
45
+ <ArrowMarkerIcon size={24} color="#888" />,
46
+ <div style={{ color: '#f70' }}><ArrowMarkerIcon size={48} /></div>,
47
+ <ArrowMarkerIcon size={ /* eslint-disable @typescript-eslint/no-explicit-any */ 'not-a-number' as any /* eslint-enable @typescript-eslint/no-explicit-any */ } />,
48
48
 
49
49
  ]); /* eslint-enable react/jsx-key */
@@ -48,11 +48,11 @@ const arrowMarkers3 = { d1h5: G, a5f4: R, c7c3: Y, g7g7: G };
48
48
  const textMarkers3 = 'G5c6,R(plus)a1,G(times)b1,B(dot)a2,Y(circle)b2';
49
49
 
50
50
  testApp([ /* eslint-disable react/jsx-key */
51
- <Chessboard squareMarkers={squareMarkers1} arrowMarkers={arrowMarkers1} textMarkers={textMarkers1} flipped={false} coordinateVisible={true} />,
52
- <Chessboard squareMarkers={squareMarkers1} arrowMarkers={arrowMarkers1} textMarkers={textMarkers1} flipped={true} coordinateVisible={true} />,
53
- <Chessboard squareMarkers={squareMarkers2} arrowMarkers={arrowMarkers2} textMarkers={textMarkers2} flipped={false} coordinateVisible={false} />,
54
- <Chessboard squareMarkers={squareMarkers2} arrowMarkers={arrowMarkers2} textMarkers={textMarkers2} flipped={true} coordinateVisible={false} />,
55
- <Chessboard squareMarkers={squareMarkers3} arrowMarkers={arrowMarkers3} textMarkers={textMarkers3} flipped={false} coordinateVisible={false} position="empty" />,
56
- <Chessboard squareMarkers={squareMarkers3} arrowMarkers={arrowMarkers3} textMarkers={textMarkers3} flipped={true} coordinateVisible={true}
57
- position="8/8/1r6/8/5k1K/8/8/8 b - - 0 1" />,
51
+ <Chessboard squareMarkers={squareMarkers1} arrowMarkers={arrowMarkers1} textMarkers={textMarkers1} flipped={false} coordinateVisible={true} />,
52
+ <Chessboard squareMarkers={squareMarkers1} arrowMarkers={arrowMarkers1} textMarkers={textMarkers1} flipped={true} coordinateVisible={true} />,
53
+ <Chessboard squareMarkers={squareMarkers2} arrowMarkers={arrowMarkers2} textMarkers={textMarkers2} flipped={false} coordinateVisible={false} />,
54
+ <Chessboard squareMarkers={squareMarkers2} arrowMarkers={arrowMarkers2} textMarkers={textMarkers2} flipped={true} coordinateVisible={false} />,
55
+ <Chessboard squareMarkers={squareMarkers3} arrowMarkers={arrowMarkers3} textMarkers={textMarkers3} flipped={false} coordinateVisible={false} position="empty" />,
56
+ <Chessboard squareMarkers={squareMarkers3} arrowMarkers={arrowMarkers3} textMarkers={textMarkers3} flipped={true} coordinateVisible={true}
57
+ position="8/8/1r6/8/5k1K/8/8/8 b - - 0 1" />,
58
58
  ]); /* eslint-enable react/jsx-key */