browserUtils.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /**
  2. * Utility functions for browser tests.
  3. *
  4. * @author n1474335 [n1474335@gmail.com]
  5. * @copyright Crown Copyright 2023
  6. * @license Apache-2.0
  7. */
  8. /** @function
  9. * Clears the recipe and input
  10. *
  11. * @param {Browser} browser - Nightwatch client
  12. */
  13. function clear(browser) {
  14. browser
  15. .useCss()
  16. .click("#clr-recipe")
  17. .click("#clr-io")
  18. .waitForElementNotPresent("#rec-list li.operation")
  19. .expect.element("#input-text .cm-content").text.that.equals("");
  20. }
  21. /** @function
  22. * Sets the input to the desired string
  23. *
  24. * @param {Browser} browser - Nightwatch client
  25. * @param {string} input - The text to populate the input with
  26. * @param {boolean} [type=true] - Whether to type the characters in by using sendKeys,
  27. * or to set the value of the editor directly (useful for special characters)
  28. */
  29. function setInput(browser, input, type=true) {
  30. clear(browser);
  31. if (type) {
  32. browser
  33. .useCss()
  34. .sendKeys("#input-text .cm-content", input)
  35. .pause(100);
  36. } else {
  37. browser.execute(text => {
  38. window.app.setInput(text);
  39. }, [input]);
  40. }
  41. }
  42. /** @function
  43. * Triggers a bake
  44. *
  45. * @param {Browser} browser - Nightwatch client
  46. */
  47. function bake(browser) {
  48. browser
  49. .click("#bake")
  50. .waitForElementNotVisible("#stale-indicator", 5000)
  51. .waitForElementNotVisible("#output-loader", 5000);
  52. }
  53. /** @function
  54. * Sets the character encoding in the input or output
  55. *
  56. * @param {Browser} browser - Nightwatch client
  57. * @param {string} io - Either "input" or "output"
  58. * @param {string} enc - The encoding to be set
  59. */
  60. function setChrEnc(browser, io, enc) {
  61. io = `#${io}-text`;
  62. browser
  63. .useCss()
  64. .click(io + " .chr-enc-value")
  65. .waitForElementVisible(io + " .chr-enc-select .cm-status-bar-select-scroll")
  66. .click("link text", enc)
  67. .waitForElementNotVisible(io + " .chr-enc-select .cm-status-bar-select-scroll")
  68. .expect.element(io + " .chr-enc-value").text.that.equals(enc);
  69. }
  70. /** @function
  71. * Sets the end of line sequence in the input or output
  72. *
  73. * @param {Browser} browser - Nightwatch client
  74. * @param {string} io - Either "input" or "output"
  75. * @param {string} eol - The sequence to set
  76. */
  77. function setEOLSeq(browser, io, eol) {
  78. io = `#${io}-text`;
  79. browser
  80. .useCss()
  81. .click(io + " .eol-value")
  82. .waitForElementVisible(io + " .eol-select .cm-status-bar-select-content")
  83. .click(`${io} .cm-status-bar-select-content a[data-val=${eol}]`)
  84. .waitForElementNotVisible(io + " .eol-select .cm-status-bar-select-content")
  85. .expect.element(io + " .eol-value").text.that.equals(eol);
  86. }
  87. /** @function
  88. * Copies whatever is currently selected
  89. *
  90. * @param {Browser} browser - Nightwatch client
  91. */
  92. function copy(browser) {
  93. browser.perform(function() {
  94. const actions = this.actions({async: true});
  95. // Ctrl + Ins used as this works on Windows, Linux and Mac
  96. return actions
  97. .keyDown(browser.Keys.CONTROL)
  98. .keyDown(browser.Keys.INSERT)
  99. .keyUp(browser.Keys.INSERT)
  100. .keyUp(browser.Keys.CONTROL);
  101. });
  102. }
  103. /** @function
  104. * Pastes into the target element
  105. *
  106. * @param {Browser} browser - Nightwatch client
  107. * @param {string} el - Target element selector
  108. */
  109. function paste(browser, el) {
  110. browser
  111. .click(el)
  112. .perform(function() {
  113. const actions = this.actions({async: true});
  114. // Shift + Ins used as this works on Windows, Linux and Mac
  115. return actions
  116. .keyDown(browser.Keys.SHIFT)
  117. .keyDown(browser.Keys.INSERT)
  118. .keyUp(browser.Keys.INSERT)
  119. .keyUp(browser.Keys.SHIFT);
  120. })
  121. .pause(100);
  122. }
  123. /** @function
  124. * Loads a recipe and input
  125. *
  126. * @param {Browser} browser - Nightwatch client
  127. * @param {string|Array<string>} opName - name of operation to be loaded, array for multiple ops
  128. * @param {string} input - input text for test
  129. * @param {Array<string>|Array<Array<string>>} args - arguments, nested if multiple ops
  130. */
  131. function loadRecipe(browser, opName, input, args) {
  132. let recipeConfig;
  133. if (typeof(opName) === "string") {
  134. recipeConfig = JSON.stringify([{
  135. "op": opName,
  136. "args": args
  137. }]);
  138. } else if (opName instanceof Array) {
  139. recipeConfig = JSON.stringify(
  140. opName.map((op, i) => {
  141. return {
  142. op: op,
  143. args: args.length ? args[i] : []
  144. };
  145. })
  146. );
  147. } else {
  148. throw new Error("Invalid operation type. Must be string or array of strings. Received: " + typeof(opName));
  149. }
  150. clear(browser);
  151. setInput(browser, input, false);
  152. browser
  153. .urlHash("recipe=" + recipeConfig)
  154. .waitForElementPresent("#rec-list li.operation");
  155. }
  156. /** @function
  157. * Tests whether the output matches a given value
  158. *
  159. * @param {Browser} browser - Nightwatch client
  160. * @param {string} expected - The expected output value
  161. */
  162. function expectOutput(browser, expected) {
  163. browser.execute(expected => {
  164. return expected === window.app.manager.output.outputEditorView.state.doc.toString();
  165. }, [expected]);
  166. }
  167. /** @function
  168. * Uploads a file using the #open-file input
  169. *
  170. * @param {Browser} browser - Nightwatch client
  171. * @param {string} filename - A path to a file in the samples directory
  172. */
  173. function uploadFile(browser, filename) {
  174. const filepath = require("path").resolve(__dirname + "/../samples/" + filename);
  175. // The file input cannot be interacted with by nightwatch while it is hidden,
  176. // so we temporarily expose it for the purposes of this test.
  177. browser.execute(() => {
  178. document.getElementById("open-file").style.display = "block";
  179. });
  180. browser
  181. .pause(100)
  182. .setValue("#open-file", filepath)
  183. .pause(100);
  184. browser.execute(() => {
  185. document.getElementById("open-file").style.display = "none";
  186. });
  187. browser.waitForElementVisible("#input-text .cm-file-details");
  188. }
  189. /** @function
  190. * Uploads a folder using the #open-folder input
  191. *
  192. * @param {Browser} browser - Nightwatch client
  193. * @param {string} foldername - A path to a folder in the samples directory
  194. */
  195. function uploadFolder(browser, foldername) {
  196. const folderpath = require("path").resolve(__dirname + "/../samples/" + foldername);
  197. // The folder input cannot be interacted with by nightwatch while it is hidden,
  198. // so we temporarily expose it for the purposes of this test.
  199. browser.execute(() => {
  200. document.getElementById("open-folder").style.display = "block";
  201. });
  202. browser
  203. .pause(100)
  204. .setValue("#open-folder", folderpath)
  205. .pause(500);
  206. browser.execute(() => {
  207. document.getElementById("open-folder").style.display = "none";
  208. });
  209. browser.waitForElementVisible("#input-text .cm-file-details");
  210. }
  211. module.exports = {
  212. clear: clear,
  213. setInput: setInput,
  214. bake: bake,
  215. setChrEnc: setChrEnc,
  216. setEOLSeq: setEOLSeq,
  217. copy: copy,
  218. paste: paste,
  219. loadRecipe: loadRecipe,
  220. expectOutput: expectOutput,
  221. uploadFile: uploadFile,
  222. uploadFolder: uploadFolder
  223. };