List.test.ts 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import {
  2. isLightboxClosed,
  3. isPageReady,
  4. isLightboxShown,
  5. expectToastShown,
  6. isElementGone,
  7. isElementThere,
  8. } from '../lib/isReady';
  9. import { ElementHandle } from 'puppeteer';
  10. import * as fs from 'fs';
  11. const BASE_URL = process.env.BASE_URL ?? 'http://localhost:8080/',
  12. DESTINATION_FONT_FILE = '/tmp/BlackAndWhitePicture-Regular.ttf';
  13. describe('WebDAV.js', () => {
  14. describe('List', () => {
  15. it('should be possible to preview items', async () => {
  16. // Wait for page JS to replace page contents
  17. await isPageReady(page, BASE_URL);
  18. await (
  19. [
  20. [
  21. '[data-full-path="/0.jpg"]',
  22. async (lightbox: ElementHandle) => {
  23. await expect(await lightbox.$('img')).toBeTruthy();
  24. },
  25. ],
  26. [
  27. '[data-full-path="/BlackAndWhitePicture-Regular.ttf"]',
  28. async (lightbox: ElementHandle) => {
  29. await expect(await lightbox.$('img')).toBeFalsy();
  30. await expect(await lightbox.$$('style')).toHaveLength(1);
  31. await expect(await lightbox.$$('h1')).toHaveLength(1);
  32. await expect(await lightbox.$$('p')).toHaveLength(4);
  33. },
  34. ],
  35. [
  36. '[data-full-path="/dummy.pdf"]',
  37. async (lightbox: ElementHandle) => {
  38. await expect(await lightbox.$('iframe')).toBeTruthy();
  39. },
  40. ],
  41. [
  42. '[data-full-path="/style.css"]',
  43. async (lightbox: ElementHandle) => {
  44. await expect(await lightbox.$('pre.language-css')).toBeTruthy();
  45. },
  46. ],
  47. [
  48. '[data-full-path="/video.mp4"]',
  49. async (lightbox: ElementHandle) => {
  50. await expect(await lightbox.$('video[autoplay]')).toBeTruthy();
  51. },
  52. ],
  53. ] as [string, (lightbox: ElementHandle) => Promise<void>][]
  54. ).reduce(
  55. async (
  56. previous: Promise<void>,
  57. [selector, expectation]
  58. ): Promise<void> => {
  59. await previous;
  60. await page.click(selector);
  61. await expectation(await isLightboxShown(page));
  62. await isLightboxClosed(page);
  63. await page.waitForTimeout(500);
  64. },
  65. Promise.resolve(null)
  66. );
  67. });
  68. it('should be possible to navigate directories', async () => {
  69. await isPageReady(page, BASE_URL);
  70. await expect(await page.$$('main ul li')).toHaveLength(23);
  71. await page.click('[data-full-path="/source.js/"]');
  72. await page.waitForTimeout(200);
  73. await expect(await page.$$('main ul li')).toHaveLength(1);
  74. await expect(await page.$('[data-full-path="/"]')).toBeTruthy();
  75. await page.click('[data-full-path="/"]');
  76. await page.waitForTimeout(200);
  77. await expect(await page.$$('main ul li')).toHaveLength(23);
  78. });
  79. it('should be possible to create a new navigable directory, rename it and delete it', async () => {
  80. await isPageReady(page, BASE_URL);
  81. page.once(
  82. 'dialog',
  83. async (dialog) => await dialog.accept('new-directory')
  84. );
  85. await page.click('.create-directory');
  86. await isElementThere(page, '[data-full-path="/new-directory/"]');
  87. await expectToastShown(
  88. page,
  89. `'new-directory' has been created.`,
  90. 'success'
  91. );
  92. await page.click('[data-full-path="/new-directory/"] .rename');
  93. await page.waitForFunction(() =>
  94. document.activeElement.matches(
  95. '[data-full-path="/new-directory/"] input[type="text"]'
  96. )
  97. );
  98. await page.keyboard.down('Control');
  99. await page.keyboard.press('Backspace');
  100. await page.keyboard.up('Control');
  101. await page.type(
  102. '[data-full-path="/new-directory/"] input[type="text"]',
  103. 'folder'
  104. );
  105. await page.keyboard.press('Enter');
  106. await expectToastShown(
  107. page,
  108. `'new-directory' successfully renamed to 'new-folder'.`,
  109. 'success'
  110. );
  111. await isElementThere(page, '[data-full-path="/new-folder/"]');
  112. page.once('dialog', async (dialog) => await dialog.accept());
  113. await page.click('[data-full-path="/new-folder/"] .delete');
  114. await isElementGone(page, '[data-full-path="/new-folder/"]');
  115. await expectToastShown(page, `'new-folder' has been deleted.`, 'success');
  116. });
  117. it('should show expected errors', async () => {
  118. await isPageReady(page, BASE_URL);
  119. await page.click('[data-full-path="/inaccessible-dir/"]');
  120. await expectToastShown(
  121. page,
  122. 'HEAD /inaccessible-dir/ failed: Forbidden (403)',
  123. 'error'
  124. );
  125. await page.click('[data-full-path="/inaccessible-file"]');
  126. await expectToastShown(
  127. page,
  128. 'GET /inaccessible-file failed: Forbidden (403)',
  129. 'error'
  130. );
  131. await page.click('[data-full-path="/inaccessible-image.jpg"]');
  132. await expectToastShown(
  133. page,
  134. 'HEAD /inaccessible-image.jpg failed: Forbidden (403)',
  135. 'error'
  136. );
  137. await page.click('[data-full-path="/inaccessible-text-file.txt"]');
  138. await expectToastShown(
  139. page,
  140. 'GET /inaccessible-text-file.txt failed: Forbidden (403)',
  141. 'error'
  142. );
  143. });
  144. it('should be possible to download a file', async () => {
  145. await isPageReady(page, BASE_URL);
  146. await expect(() => fs.accessSync(DESTINATION_FONT_FILE)).toThrow();
  147. await page
  148. .target()
  149. .createCDPSession()
  150. .then((client) =>
  151. client.send('Page.setDownloadBehavior', {
  152. behavior: 'allow',
  153. downloadPath: '/tmp',
  154. })
  155. );
  156. await page.click(
  157. '[data-full-path="/BlackAndWhitePicture-Regular.ttf"] [download]'
  158. );
  159. // wait for the file to download
  160. await page.waitForTimeout(400);
  161. await expect(() => fs.accessSync(DESTINATION_FONT_FILE)).not.toThrow();
  162. fs.rmSync(DESTINATION_FONT_FILE);
  163. });
  164. it('should be possible to upload a file', async () => {
  165. await isPageReady(page, BASE_URL);
  166. const elementHandle = (await page.$(
  167. 'input[type=file]'
  168. )) as ElementHandle<HTMLInputElement>;
  169. await elementHandle.uploadFile('./package.json');
  170. await expectToastShown(
  171. page,
  172. `'package.json' has been successfully uploaded.`,
  173. 'success'
  174. );
  175. await page.click('[data-full-path="/package.json"]');
  176. await page.once('dialog', async (dialog) => await dialog.accept());
  177. await page.click('[data-full-path="/package.json"] .delete');
  178. await isElementGone(page, '[data-full-path="/package.json"]');
  179. await expectToastShown(
  180. page,
  181. `'package.json' has been deleted.`,
  182. 'success'
  183. );
  184. });
  185. });
  186. beforeAll(async () => {
  187. try {
  188. fs.accessSync(DESTINATION_FONT_FILE);
  189. fs.rmSync(DESTINATION_FONT_FILE);
  190. } catch (e) {
  191. // we don't need to do anything here
  192. }
  193. });
  194. });