search.spec.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. import { expect, test } from '@playwright/test';
  2. test('Search page with "q" param is successfully loaded', async ({ page }) => {
  3. // Navigate to the search page with query parameters
  4. await page.goto('/_search?q=alerts');
  5. // Confirm search result elements are visible
  6. await expect(page.getByTestId('search-result-base')).toBeVisible();
  7. await expect(page.getByTestId('search-result-list')).toBeVisible();
  8. await expect(page.getByTestId('search-result-content')).toBeVisible();
  9. await expect(page.locator('.wiki')).toBeVisible();
  10. });
  11. test('checkboxes behaviors', async ({ page }) => {
  12. // Navigate to the search page with query parameters
  13. await page.goto('/_search?q=alerts');
  14. // Confirm search result elements are visible
  15. await expect(page.getByTestId('search-result-base')).toBeVisible();
  16. await expect(page.getByTestId('search-result-list')).toBeVisible();
  17. await expect(page.getByTestId('search-result-content')).toBeVisible();
  18. await expect(page.locator('.wiki')).toBeVisible();
  19. // Click the first checkbox
  20. await page.getByTestId('cb-select').first().click({ force: true });
  21. // Unclick the first checkbox
  22. await page.getByTestId('cb-select').first().click({ force: true });
  23. // Click the select all checkbox
  24. await page
  25. .getByTestId('delete-control-button')
  26. .first()
  27. .click({ force: true });
  28. await page.getByTestId('cb-select-all').click({ force: true });
  29. // Unclick the first checkbox after selecting all
  30. await page.getByTestId('cb-select').first().click({ force: true });
  31. // Click the first checkbox again
  32. await page.getByTestId('cb-select').first().click({ force: true });
  33. // Unclick the select all checkbox
  34. await page.getByTestId('cb-select').first().click({ force: true });
  35. });
  36. test('successfully loads /_private-legacy-pages', async ({ page }) => {
  37. await page.goto('/_private-legacy-pages');
  38. // Confirm search result elements are visible
  39. await expect(
  40. page.locator('[data-testid="search-result-base"]'),
  41. ).toBeVisible();
  42. await expect(
  43. page.locator('[data-testid="search-result-private-legacy-pages"]'),
  44. ).toBeVisible();
  45. });
  46. test('Search all pages by word', async ({ page }) => {
  47. await page.goto('/');
  48. await page.getByTestId('open-search-modal-button').click();
  49. await expect(page.getByTestId('search-modal')).toBeVisible();
  50. await page.locator('.form-control').fill('sand');
  51. await expect(page.locator('.search-menu-item').first()).toBeVisible();
  52. });
  53. test.describe
  54. .serial('Search all pages', () => {
  55. const tag = 'help';
  56. const searchText = `tag:${tag}`;
  57. test('Successfully created tags', async ({ page }) => {
  58. await page.goto('/');
  59. // open Edit Tags Modal to add tag
  60. await page.locator('.grw-side-contents-sticky-container').isVisible();
  61. await page.locator('#edit-tags-btn-wrapper-for-tooltip').click();
  62. await expect(page.locator('#edit-tag-modal')).toBeVisible();
  63. await page.locator('.rbt-input-main').fill(tag);
  64. await page.locator('#tag-typeahead-asynctypeahead-item-0').click();
  65. await page.getByTestId('tag-edit-done-btn').click();
  66. });
  67. test('Search all pages by tag is successfully loaded', async ({ page }) => {
  68. await page.goto('/');
  69. // Search
  70. await page.getByTestId('open-search-modal-button').click();
  71. await expect(page.getByTestId('search-modal')).toBeVisible();
  72. await page.locator('.form-control').fill(searchText);
  73. await page.getByTestId('search-all-menu-item').click();
  74. // Confirm search result elements are visible
  75. const searchResultList = page.getByTestId('search-result-list');
  76. await expect(searchResultList).toBeVisible();
  77. await expect(searchResultList.locator('li')).toHaveCount(1);
  78. });
  79. test('Successfully order page search results by tag', async ({ page }) => {
  80. await page.goto('/');
  81. await page.locator('.grw-tag-simple-bar').locator('a').click();
  82. expect(page.getByTestId('search-result-base')).toBeVisible();
  83. expect(page.getByTestId('search-result-list')).toBeVisible();
  84. expect(page.getByTestId('search-result-content')).toBeVisible();
  85. });
  86. });
  87. test.describe('Sort with dropdown', () => {
  88. test.beforeEach(async ({ page }) => {
  89. await page.goto('/_search?q=sand');
  90. await expect(page.getByTestId('search-result-base')).toBeVisible();
  91. await expect(page.getByTestId('search-result-list')).toBeVisible();
  92. await expect(page.getByTestId('search-result-content')).toBeVisible();
  93. // open sort dropdown
  94. await page.locator('.search-control').locator('button').first().click();
  95. });
  96. test('Open sort dropdown', async ({ page }) => {
  97. await expect(
  98. page.locator('.search-control .dropdown-menu.show'),
  99. ).toBeVisible();
  100. });
  101. test('Sort by relevance', async ({ page }) => {
  102. const dropdownMenu = page.locator('.search-control .dropdown-menu.show');
  103. await expect(dropdownMenu).toBeVisible();
  104. await dropdownMenu.locator('.dropdown-item').nth(0).click();
  105. await expect(page.getByTestId('search-result-base')).toBeVisible();
  106. await expect(page.getByTestId('search-result-list')).toBeVisible();
  107. await expect(page.getByTestId('search-result-content')).toBeVisible();
  108. });
  109. test('Sort by creation date', async ({ page }) => {
  110. const dropdownMenu = page.locator('.search-control .dropdown-menu.show');
  111. await expect(dropdownMenu).toBeVisible();
  112. await dropdownMenu.locator('.dropdown-item').nth(1).click();
  113. await expect(page.getByTestId('search-result-base')).toBeVisible();
  114. await expect(page.getByTestId('search-result-list')).toBeVisible();
  115. await expect(page.getByTestId('search-result-content')).toBeVisible();
  116. });
  117. test('Sort by last update date', async ({ page }) => {
  118. const dropdownMenu = page.locator('.search-control .dropdown-menu.show');
  119. await expect(dropdownMenu).toBeVisible();
  120. await dropdownMenu.locator('.dropdown-item').nth(2).click();
  121. await expect(page.getByTestId('search-result-base')).toBeVisible();
  122. await expect(page.getByTestId('search-result-list')).toBeVisible();
  123. await expect(page.getByTestId('search-result-content')).toBeVisible();
  124. });
  125. });
  126. test.describe('Search and use', () => {
  127. test.beforeEach(async ({ page }) => {
  128. await page.goto('/_search?q=alerts');
  129. await expect(page.getByTestId('search-result-base')).toBeVisible();
  130. await expect(page.getByTestId('search-result-list')).toBeVisible();
  131. await expect(page.getByTestId('search-result-content')).toBeVisible();
  132. await page
  133. .getByTestId('page-list-item-L')
  134. .first()
  135. .getByTestId('open-page-item-control-btn')
  136. .click();
  137. await expect(page.locator('.dropdown-menu.show')).toBeVisible();
  138. });
  139. test('Successfully the dropdown is opened', async ({ page }) => {
  140. await expect(page.locator('.dropdown-menu.show')).toBeVisible();
  141. });
  142. test('Successfully add bookmark', async ({ page }) => {
  143. const dropdonwMenu = page.locator('.dropdown-menu.show');
  144. await expect(dropdonwMenu).toBeVisible();
  145. // Add bookmark
  146. await dropdonwMenu.getByTestId('add-bookmark-btn').click();
  147. await expect(
  148. page
  149. .getByTestId('search-result-content')
  150. .locator('.btn-bookmark.active')
  151. .first(),
  152. ).toBeVisible();
  153. });
  154. test('Successfully open duplicate modal', async ({ page }) => {
  155. const dropdonwMenu = page.locator('.dropdown-menu.show');
  156. await expect(dropdonwMenu).toBeVisible();
  157. await dropdonwMenu.getByTestId('open-page-duplicate-modal-btn').click();
  158. await expect(page.getByTestId('page-duplicate-modal')).toBeVisible();
  159. });
  160. test('Successfully open move/rename modal', async ({ page }) => {
  161. const dropdonwMenu = page.locator('.dropdown-menu.show');
  162. await expect(dropdonwMenu).toBeVisible();
  163. await dropdonwMenu.getByTestId('rename-page-btn').click();
  164. await expect(page.getByTestId('page-rename-modal')).toBeVisible();
  165. });
  166. test('Successfully open delete modal', async ({ page }) => {
  167. const dropdonwMenu = page.locator('.dropdown-menu.show');
  168. await expect(dropdonwMenu).toBeVisible();
  169. await dropdonwMenu.getByTestId('open-page-delete-modal-btn').click();
  170. await expect(page.getByTestId('page-delete-modal')).toBeVisible();
  171. });
  172. });
  173. test('Search current tree by word is successfully loaded', async ({ page }) => {
  174. await page.goto('/');
  175. const searchText = 'GROWI';
  176. await page.getByTestId('open-search-modal-button').click();
  177. await expect(page.getByTestId('search-modal')).toBeVisible();
  178. await page.locator('.form-control').fill(searchText);
  179. await page.getByTestId('search-prefix-menu-item').click();
  180. await expect(page.getByTestId('search-result-base')).toBeVisible();
  181. await expect(page.getByTestId('search-result-list')).toBeVisible();
  182. await expect(page.getByTestId('search-result-content')).toBeVisible();
  183. });
  184. test.describe('Search result navigation and repeated search', () => {
  185. test('Repeated search works', async ({ page }) => {
  186. // Step 1: Start from the home page and reload to clear any state
  187. await page.goto('/');
  188. await page.reload();
  189. // Step 2: Open search modal and search for "sandbox"
  190. await page.getByTestId('open-search-modal-button').click();
  191. await expect(page.getByTestId('search-modal')).toBeVisible();
  192. await page.locator('.form-control').fill('sandbox');
  193. // Step 3: Submit the search by clicking on "search in all" menu item
  194. await expect(page.getByTestId('search-all-menu-item')).toBeVisible();
  195. await page.getByTestId('search-all-menu-item').click();
  196. // Step 4: Verify that the search page is displayed with results
  197. await expect(page.getByTestId('search-result-base')).toBeVisible();
  198. await expect(page.getByTestId('search-result-list')).toBeVisible();
  199. await expect(page.getByTestId('search-result-content')).toBeVisible();
  200. await expect(page).toHaveURL(/\/_search\?q=sandbox/);
  201. // Step 5: Click on the first search result to navigate to a page
  202. const sandboxPageLink = page
  203. .getByTestId('search-result-list')
  204. .getByRole('link', { name: 'Sandbox' })
  205. .first();
  206. await sandboxPageLink.click();
  207. await expect(page).toHaveTitle(/Sandbox/);
  208. // Step 6: Wait for leaving search results and verify page content is displayed
  209. await expect(page.getByTestId('search-result-base')).not.toBeVisible();
  210. // Verify page body is rendered (not empty due to stale atom data)
  211. await expect(page.locator('.wiki')).toBeVisible();
  212. await expect(page.locator('.wiki')).not.toBeEmpty();
  213. // Step 7: From the navigated page, open search modal again
  214. await page.getByTestId('open-search-modal-button').click();
  215. await expect(page.getByTestId('search-modal')).toBeVisible();
  216. // Step 8: Search for the same keyword ("sandbox")
  217. await page.locator('.form-control').fill('sandbox');
  218. // Step 9: Submit the search by clicking on "search in all" menu item
  219. await expect(page.getByTestId('search-all-menu-item')).toBeVisible();
  220. await page.getByTestId('search-all-menu-item').click();
  221. // Step 10: Verify that the search page is displayed with results
  222. await expect(page.getByTestId('search-result-base')).toBeVisible();
  223. await expect(page.getByTestId('search-result-list')).toBeVisible();
  224. await expect(page.getByTestId('search-result-content')).toBeVisible();
  225. await expect(page).toHaveURL(/\/_search\?q=sandbox/);
  226. // Step 11: Click on the second search result to navigate to a page
  227. const mathPageLink = page
  228. .getByTestId('search-result-list')
  229. .getByRole('link', { name: 'Math' })
  230. .first();
  231. await mathPageLink.click();
  232. // and verify the page that is not Sandbox is loaded
  233. await expect(page).not.toHaveTitle(/Sandbox/);
  234. // Step 12: Verify page body is rendered (not empty due to stale atom data)
  235. await expect(page.locator('.wiki')).toBeVisible();
  236. await expect(page.locator('.wiki')).not.toBeEmpty();
  237. });
  238. });