fs.spec.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import fsp from 'fs/promises';
  2. import path from 'path';
  3. import { expect } from '@playwright/test'
  4. import { test } from './fixtures';
  5. import { searchPage, captureConsoleWithPrefix, closeSearchBox, createPage, IsWindows } from './utils';
  6. test('create file on disk then delete', async ({ page, block, graphDir }) => {
  7. // Since have to wait for file watchers
  8. test.slow();
  9. // Special page names: namespaced, chars require escaping, chars require unicode normalization, "%" chars, "%" with 2 hexdigests
  10. const testCases = [
  11. {pageTitle: "User:John", fileName: "User%3AJohn"},
  12. // invalid url decode escaping as %ff is not parsable but match the common URL encode regex
  13. {pageTitle: "#%ff", fileName: "#%ff"},
  14. // valid url decode escaping
  15. {pageTitle: "#%23", fileName: "#%2523"},
  16. {pageTitle: "@!#%", fileName: "@!#%"},
  17. {pageTitle: "aàáâ", fileName: "aàáâ"},
  18. {pageTitle: "#%gggg", fileName: "#%gggg"}
  19. ]
  20. if (!IsWindows)
  21. testCases.push({pageTitle: "User:Bob", fileName: "User:Bob"})
  22. function getFullPath(fileName: string) {
  23. return path.join(graphDir, "pages", `${fileName}.md`);
  24. }
  25. // Test putting files on disk
  26. for (const {pageTitle, fileName} of testCases) {
  27. // Put the file on disk
  28. const filePath = getFullPath(fileName);
  29. await fsp.writeFile(filePath, `- content for ${pageTitle}`);
  30. await captureConsoleWithPrefix(page, "Parsing finished:", 5000)
  31. // Check that the page is created
  32. const results = await searchPage(page, pageTitle);
  33. const firstResultRow = await results[0].innerText()
  34. expect(firstResultRow).toContain(pageTitle);
  35. expect(firstResultRow).not.toContain("New");
  36. await closeSearchBox(page);
  37. }
  38. // Test removing files on disk
  39. for (const {pageTitle, fileName} of testCases) {
  40. // Remove the file on disk
  41. const filePath = getFullPath(fileName);
  42. await fsp.unlink(filePath);
  43. await captureConsoleWithPrefix(page, "Delete page:", 5000);
  44. // Test that the page is deleted
  45. const results = await searchPage(page, pageTitle);
  46. const firstResultRow = await results[0].innerText()
  47. expect(firstResultRow).toContain("New");
  48. await closeSearchBox(page);
  49. }
  50. });
  51. test("Rename file on disk", async ({ page, block, graphDir }) => {
  52. // Since have to wait for file watchers
  53. test.slow();
  54. const testCases = [
  55. // Normal -> NameSpace
  56. {pageTitle: "User:John", fileName: "User%3AJohn",
  57. newPageTitle: "User/John", newFileName: "User___John"},
  58. // NameSpace -> Normal
  59. {pageTitle: "#/%23", fileName: "#___%2523",
  60. newPageTitle: "#%23", newFileName: "#%2523"}
  61. ]
  62. if (!IsWindows)
  63. testCases.push({pageTitle: "User:Bob", fileName: "User:Bob",
  64. newPageTitle: "User/Bob", newFileName: "User___Bob"})
  65. function getFullPath(fileName: string) {
  66. return path.join(graphDir, "pages", `${fileName}.md`);
  67. }
  68. // Test putting files on disk
  69. for (const {pageTitle, fileName} of testCases) {
  70. // Put the file on disk
  71. const filePath = getFullPath(fileName);
  72. await fsp.writeFile(filePath, `- content for ${pageTitle}`);
  73. await captureConsoleWithPrefix(page, "Parsing finished:", 5000)
  74. // Check that the page is created
  75. const results = await searchPage(page, pageTitle);
  76. const firstResultRow = await results[0].innerText()
  77. expect(firstResultRow).toContain(pageTitle);
  78. expect(firstResultRow).not.toContain("New");
  79. await closeSearchBox(page);
  80. }
  81. // Test renaming files on disk
  82. for (const {pageTitle, fileName, newPageTitle, newFileName} of testCases) {
  83. // Rename the file on disk
  84. const filePath = getFullPath(fileName);
  85. const newFilePath = getFullPath(newFileName);
  86. await fsp.rename(filePath, newFilePath);
  87. await captureConsoleWithPrefix(page, "Parsing finished:", 5000);
  88. // Test that the page is renamed
  89. const results = await searchPage(page, newPageTitle);
  90. const firstResultRow = await results[0].innerText()
  91. expect(firstResultRow).toContain(newPageTitle);
  92. expect(firstResultRow).not.toContain(pageTitle);
  93. expect(firstResultRow).not.toContain("New");
  94. await closeSearchBox(page);
  95. }
  96. })
  97. test('special page names', async ({ page, block, graphDir }) => {
  98. const testCases = [
  99. {pageTitle: "User:John", fileName: "User%3AJohn"},
  100. // FIXME: Logseq can't creat page starting with "#" in search panel
  101. {pageTitle: "_#%ff", fileName: "_%23%25ff"},
  102. {pageTitle: "_#%23", fileName: "_%23%2523"},
  103. {pageTitle: "@!#%", fileName: "@!%23%"},
  104. {pageTitle: "aàáâ", fileName: "aàáâ"},
  105. {pageTitle: "_#%gggg", fileName: "_%23%gggg"}
  106. ]
  107. // Test putting files on disk
  108. for (const {pageTitle, fileName} of testCases) {
  109. // Create page in Logseq
  110. await createPage(page, pageTitle)
  111. const text = `content for ${pageTitle}`
  112. await block.mustFill(text)
  113. await page.keyboard.press("Enter")
  114. // Wait for the file to be created on disk
  115. await page.waitForTimeout(2000);
  116. // Validate that the file is created on disk with the content
  117. const filePath = path.join(graphDir, "pages", `${fileName}.md`);
  118. const fileContent = await fsp.readFile(filePath, "utf8");
  119. expect(fileContent).toContain(text);
  120. }
  121. });