suggestionsBrowserKey.mjs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. import { describe, it, before, after } from 'mocha'
  2. import { expect } from 'chai'
  3. import { By, Condition } from 'selenium-webdriver'
  4. import {
  5. DEFAULT_UI_WAIT_MS,
  6. getRootAndWait,
  7. getActionButton,
  8. takeScreenshotOnFailure,
  9. waitForDashboardLoaded,
  10. waitForLogsPage,
  11. waitForArgumentFormPage,
  12. waitForArgumentFormReady,
  13. waitForExecutionComplete,
  14. } from '../../lib/elements.js'
  15. async function ensureOnDashboard() {
  16. let url = await webdriver.getCurrentUrl()
  17. if (url.includes('/logs/')) {
  18. const backButton = await webdriver.findElement(By.css('button[title="Go back"]'))
  19. await backButton.click()
  20. await webdriver.wait(
  21. new Condition('wait for argument form after logs back', async () => {
  22. const currentUrl = await webdriver.getCurrentUrl()
  23. return currentUrl.includes('/argumentForm')
  24. }),
  25. DEFAULT_UI_WAIT_MS
  26. )
  27. url = await webdriver.getCurrentUrl()
  28. }
  29. if (url.includes('/argumentForm')) {
  30. const cancelButton = await webdriver.findElement(By.css('button[name="cancel"]'))
  31. await cancelButton.click()
  32. await waitForDashboardLoaded()
  33. }
  34. const actionButtons = await webdriver.findElements(By.css('[title="Test suggestionsBrowserKey"]'))
  35. if (actionButtons.length === 1) {
  36. return
  37. }
  38. await getRootAndWait()
  39. }
  40. async function openArgumentForm() {
  41. await ensureOnDashboard()
  42. const btn = await getActionButton(webdriver, 'Test suggestionsBrowserKey')
  43. await btn.click()
  44. await waitForArgumentFormPage()
  45. await waitForArgumentFormReady()
  46. }
  47. async function getTestInput() {
  48. return await webdriver.findElement(By.id('testInput'))
  49. }
  50. async function getTestInput2() {
  51. return await webdriver.findElement(By.id('testInput2'))
  52. }
  53. async function getDatalistOptions(inputName = 'testInput') {
  54. return await webdriver.findElements(By.css(`datalist#${inputName}-choices option`))
  55. }
  56. async function submitForm() {
  57. const submitButton = await webdriver.findElement(By.css('button[name="start"]'))
  58. await submitButton.click()
  59. }
  60. async function getLocalStorageItem(key) {
  61. return await webdriver.executeScript(`return localStorage.getItem('${key}')`)
  62. }
  63. async function clearLocalStorage() {
  64. await webdriver.executeScript('return localStorage.clear()')
  65. }
  66. describe('config: suggestionsBrowserKey', function () {
  67. before(async function () {
  68. await runner.start('suggestionsBrowserKey')
  69. await getRootAndWait()
  70. })
  71. after(async () => {
  72. await runner.stop()
  73. })
  74. afterEach(function () {
  75. takeScreenshotOnFailure(this.currentTest, webdriver)
  76. })
  77. it('Input fields with suggestionsBrowserKey are rendered', async function () {
  78. await openArgumentForm()
  79. const input1 = await getTestInput()
  80. expect(await input1.getTagName()).to.equal('input')
  81. expect(await input1.getAttribute('type')).to.equal('text')
  82. const label1 = await webdriver.findElement(By.css('label[for="testInput"]'))
  83. expect(await label1.getText()).to.contain('Test Input')
  84. const input2 = await getTestInput2()
  85. expect(await input2.getTagName()).to.equal('input')
  86. expect(await input2.getAttribute('type')).to.equal('text')
  87. const label2 = await webdriver.findElement(By.css('label[for="testInput2"]'))
  88. expect(await label2.getText()).to.contain('Test Input 2')
  89. })
  90. it('Submitting form saves value to localStorage', async function () {
  91. await clearLocalStorage()
  92. await openArgumentForm()
  93. const input = await getTestInput()
  94. // Use default argument type "ascii" (alphanumeric only) so tests pass when
  95. // config does not set a looser type (e.g. CI merge base without type lines).
  96. const testValue = 'testvalue123'
  97. await input.clear()
  98. await input.sendKeys(testValue)
  99. await submitForm()
  100. await waitForLogsPage()
  101. await waitForExecutionComplete()
  102. const stored = await getLocalStorageItem('olivetin-suggestions-test-suggestions-key')
  103. expect(stored).to.not.be.null
  104. const suggestions = JSON.parse(stored)
  105. expect(suggestions).to.be.an('array')
  106. expect(suggestions).to.include(testValue)
  107. })
  108. it('Previously saved values appear in datalist', async function () {
  109. const testValue = 'savedsuggestion456'
  110. await webdriver.executeScript(`
  111. const key = 'olivetin-suggestions-test-suggestions-key';
  112. localStorage.setItem(key, JSON.stringify(['${testValue}']));
  113. `)
  114. await openArgumentForm()
  115. const datalist = await webdriver.findElement(By.id('testInput-choices'))
  116. expect(datalist).to.not.be.null
  117. const options = await getDatalistOptions()
  118. expect(options.length).to.be.greaterThan(0)
  119. let foundValue = false
  120. for (const option of options) {
  121. const value = await option.getAttribute('value')
  122. if (value === testValue) {
  123. foundValue = true
  124. break
  125. }
  126. }
  127. expect(foundValue).to.be.true
  128. })
  129. it('Multiple submissions accumulate suggestions', async function () {
  130. await clearLocalStorage()
  131. await openArgumentForm()
  132. const input1 = await getTestInput()
  133. await input1.clear()
  134. await input1.sendKeys('firstvalue')
  135. await submitForm()
  136. await waitForLogsPage()
  137. await waitForExecutionComplete()
  138. await openArgumentForm()
  139. const input2 = await getTestInput()
  140. await input2.clear()
  141. await input2.sendKeys('secondvalue')
  142. await submitForm()
  143. await waitForLogsPage()
  144. await waitForExecutionComplete()
  145. const stored = await getLocalStorageItem('olivetin-suggestions-test-suggestions-key')
  146. expect(stored).to.not.be.null
  147. const suggestions = JSON.parse(stored)
  148. expect(suggestions).to.be.an('array')
  149. expect(suggestions).to.include('firstvalue')
  150. expect(suggestions).to.include('secondvalue')
  151. expect(suggestions[0]).to.equal('secondvalue')
  152. })
  153. it('Empty values are not saved to localStorage', async function () {
  154. await clearLocalStorage()
  155. await openArgumentForm()
  156. const input = await getTestInput()
  157. await input.clear()
  158. await submitForm()
  159. await waitForLogsPage()
  160. await waitForExecutionComplete()
  161. const stored = await getLocalStorageItem('olivetin-suggestions-test-suggestions-key')
  162. if (stored !== null) {
  163. const suggestions = JSON.parse(stored)
  164. expect(suggestions).to.be.an('array')
  165. expect(suggestions).to.have.length(0)
  166. }
  167. })
  168. it('Suggestions are shared across inputs with the same suggestionsBrowserKey', async function () {
  169. this.timeout(12000)
  170. await clearLocalStorage()
  171. await openArgumentForm()
  172. const input1 = await getTestInput()
  173. await input1.clear()
  174. await input1.sendKeys('sharedfrominput1')
  175. await submitForm()
  176. await waitForLogsPage()
  177. await waitForExecutionComplete()
  178. await openArgumentForm()
  179. const datalist1 = await webdriver.findElement(By.id('testInput-choices'))
  180. expect(datalist1).to.not.be.null
  181. const options1 = await getDatalistOptions('testInput')
  182. let foundInInput1 = false
  183. for (const option of options1) {
  184. const value = await option.getAttribute('value')
  185. if (value === 'sharedfrominput1') {
  186. foundInInput1 = true
  187. break
  188. }
  189. }
  190. expect(foundInInput1).to.be.true
  191. const datalist2 = await webdriver.findElement(By.id('testInput2-choices'))
  192. expect(datalist2).to.not.be.null
  193. const options2 = await getDatalistOptions('testInput2')
  194. let foundInInput2 = false
  195. for (const option of options2) {
  196. const value = await option.getAttribute('value')
  197. if (value === 'sharedfrominput1') {
  198. foundInInput2 = true
  199. break
  200. }
  201. }
  202. expect(foundInInput2).to.be.true
  203. const input2 = await getTestInput2()
  204. await input2.clear()
  205. await input2.sendKeys('sharedfrominput2')
  206. await submitForm()
  207. await waitForLogsPage()
  208. await waitForExecutionComplete()
  209. await openArgumentForm()
  210. const options1After = await getDatalistOptions('testInput')
  211. let foundValue1 = false
  212. let foundValue2 = false
  213. for (const option of options1After) {
  214. const value = await option.getAttribute('value')
  215. if (value === 'sharedfrominput1') {
  216. foundValue1 = true
  217. }
  218. if (value === 'sharedfrominput2') {
  219. foundValue2 = true
  220. }
  221. }
  222. expect(foundValue1).to.be.true
  223. expect(foundValue2).to.be.true
  224. const options2After = await getDatalistOptions('testInput2')
  225. foundValue1 = false
  226. foundValue2 = false
  227. for (const option of options2After) {
  228. const value = await option.getAttribute('value')
  229. if (value === 'sharedfrominput1') {
  230. foundValue1 = true
  231. }
  232. if (value === 'sharedfrominput2') {
  233. foundValue2 = true
  234. }
  235. }
  236. expect(foundValue1).to.be.true
  237. expect(foundValue2).to.be.true
  238. })
  239. })