@@ -10,48 +10,38 @@ test.describe('URL-based Navigation (Realworld Issue #691)', () => {
1010
1111 test ( '/ should show Global Feed for everyone' , async ( { page } ) => {
1212 await page . goto ( '/' ) ;
13-
1413 // Should see Global Feed active
1514 await expect ( page . locator ( '.nav-link:has-text("Global Feed")' ) ) . toHaveClass ( / a c t i v e / ) ;
16-
1715 // Should see articles
18- await expect ( page . locator ( '.article-preview' ) . first ( ) ) . toBeVisible ( { timeout : 10000 } ) ;
19-
16+ await expect ( page . locator ( '.article-preview' ) . first ( ) ) . toBeVisible ( { timeout : 2000 } ) ;
2017 // URL should be /
2118 await expect ( page ) . toHaveURL ( '/' ) ;
2219 } ) ;
2320
2421 test ( '/?feed=following should show Your Feed (authenticated)' , async ( { page } ) => {
2522 const user = generateUniqueUser ( ) ;
2623 await register ( page , user . username , user . email , user . password ) ;
27-
2824 await page . goto ( '/?feed=following' ) ;
29-
3025 // Should see Your Feed active
3126 await expect ( page . locator ( '.nav-link:has-text("Your Feed")' ) ) . toHaveClass ( / a c t i v e / ) ;
32-
3327 // URL should have feed param
3428 await expect ( page ) . toHaveURL ( '/?feed=following' ) ;
3529 } ) ;
3630
3731 test ( '/?feed=following should redirect to /login when not authenticated' , async ( { page } ) => {
3832 await page . goto ( '/?feed=following' ) ;
39-
4033 // Should be redirected to login
4134 await expect ( page ) . toHaveURL ( '/login' ) ;
4235 } ) ;
4336
4437 test ( '/tag/:tag should filter by tag' , async ( { page } ) => {
4538 await page . goto ( '/' ) ;
46- await page . waitForSelector ( '.sidebar .tag-list' , { timeout : 10000 } ) ;
47-
39+ await page . waitForSelector ( '.sidebar .tag-list' , { timeout : 2000 } ) ;
4840 // Get a tag from the sidebar
4941 const firstTag = await page . locator ( '.sidebar .tag-list .tag-pill' ) . first ( ) . textContent ( ) ;
5042 expect ( firstTag ) . toBeTruthy ( ) ;
51-
5243 // Navigate directly to the tag URL
5344 await page . goto ( `/tag/${ firstTag ?. trim ( ) } ` ) ;
54-
5545 // Should see the tag filter active
5646 await expect ( page . locator ( `.nav-link:has-text("${ firstTag ?. trim ( ) } ")` ) ) . toBeVisible ( ) ;
5747 await expect ( page . locator ( `.nav-link:has-text("${ firstTag ?. trim ( ) } ")` ) ) . toHaveClass ( / a c t i v e / ) ;
@@ -60,14 +50,11 @@ test.describe('URL-based Navigation (Realworld Issue #691)', () => {
6050 test ( 'tabs should have correct href attributes' , async ( { page } ) => {
6151 const user = generateUniqueUser ( ) ;
6252 await register ( page , user . username , user . email , user . password ) ;
63-
6453 await page . goto ( '/' ) ;
65- await page . waitForSelector ( '.feed-toggle' , { timeout : 10000 } ) ;
66-
54+ await page . waitForSelector ( '.feed-toggle' , { timeout : 2000 } ) ;
6755 // Your Feed should link to /?feed=following
6856 const yourFeedLink = page . locator ( '.nav-link:has-text("Your Feed")' ) ;
6957 await expect ( yourFeedLink ) . toHaveAttribute ( 'href' , '/?feed=following' ) ;
70-
7158 // Global Feed should link to /
7259 const globalFeedLink = page . locator ( '.nav-link:has-text("Global Feed")' ) ;
7360 await expect ( globalFeedLink ) . toHaveAttribute ( 'href' , '/' ) ;
@@ -76,13 +63,10 @@ test.describe('URL-based Navigation (Realworld Issue #691)', () => {
7663 test ( 'clicking Your Feed should navigate to /?feed=following' , async ( { page } ) => {
7764 const user = generateUniqueUser ( ) ;
7865 await register ( page , user . username , user . email , user . password ) ;
79-
8066 // Should be at /
8167 await expect ( page ) . toHaveURL ( '/' ) ;
82-
8368 // Click Your Feed
8469 await page . click ( '.nav-link:has-text("Your Feed")' ) ;
85-
8670 // Should navigate to /?feed=following
8771 await expect ( page ) . toHaveURL ( '/?feed=following' ) ;
8872 await expect ( page . locator ( '.nav-link:has-text("Your Feed")' ) ) . toHaveClass ( / a c t i v e / ) ;
@@ -91,14 +75,11 @@ test.describe('URL-based Navigation (Realworld Issue #691)', () => {
9175 test ( 'clicking Global Feed should navigate to /' , async ( { page } ) => {
9276 const user = generateUniqueUser ( ) ;
9377 await register ( page , user . username , user . email , user . password ) ;
94-
9578 // Go to Your Feed first
9679 await page . goto ( '/?feed=following' ) ;
9780 await expect ( page . locator ( '.nav-link:has-text("Your Feed")' ) ) . toHaveClass ( / a c t i v e / ) ;
98-
9981 // Click Global Feed
10082 await page . click ( '.nav-link:has-text("Global Feed")' ) ;
101-
10283 // Should navigate to /
10384 await expect ( page ) . toHaveURL ( '/' ) ;
10485 await expect ( page . locator ( '.nav-link:has-text("Global Feed")' ) ) . toHaveClass ( / a c t i v e / ) ;
@@ -107,16 +88,12 @@ test.describe('URL-based Navigation (Realworld Issue #691)', () => {
10788 test ( 'empty Your Feed shows helpful message with link to Global Feed' , async ( { page } ) => {
10889 const user = generateUniqueUser ( ) ;
10990 await register ( page , user . username , user . email , user . password ) ;
110-
11191 await page . goto ( '/?feed=following' ) ;
112-
11392 // Wait for loading to complete
114- await page . waitForSelector ( '.empty-feed-message' , { timeout : 10000 } ) ;
115-
93+ await page . waitForSelector ( '.empty-feed-message' , { timeout : 2000 } ) ;
11694 // Should show helpful empty message
11795 const emptyMessage = page . locator ( '.empty-feed-message' ) ;
11896 await expect ( emptyMessage ) . toContainText ( 'Your feed is empty' ) ;
119-
12097 // Should have a link to Global Feed
12198 const globalFeedLink = emptyMessage . locator ( 'a[href="/"]' ) ;
12299 await expect ( globalFeedLink ) . toBeVisible ( ) ;
@@ -135,23 +112,17 @@ test.describe('Pagination', () => {
135112 const testUser = generateUniqueUser ( ) ;
136113 const token = await registerUserViaAPI ( request , testUser ) ;
137114 await createManyArticles ( request , token , 15 , uniqueTag ) ;
138-
139115 // Login as the user who created the articles (session isolation)
140116 await login ( page , testUser . email , testUser . password ) ;
141-
142117 // Navigate to the tag page - this shows ONLY our articles
143118 await page . goto ( `/tag/${ uniqueTag } ` ) ;
144- await page . waitForSelector ( '.article-preview' , { timeout : 15000 } ) ;
145-
119+ await page . waitForSelector ( '.article-preview' , { timeout : 2000 } ) ;
146120 // Should have pagination (15 articles = 2 pages with limit 10)
147- await expect ( page . locator ( '.pagination button:has-text("2")' ) ) . toBeVisible ( { timeout : 15000 } ) ;
148-
121+ await expect ( page . locator ( '.pagination button:has-text("2")' ) ) . toBeVisible ( { timeout : 2000 } ) ;
149122 // Click page 2
150123 await page . click ( '.pagination button:has-text("2")' ) ;
151-
152124 // URL should have ?page=2
153125 await expect ( page ) . toHaveURL ( new RegExp ( `/tag/${ uniqueTag } \\?page=2` ) ) ;
154-
155126 // Page 2 should be active
156127 await expect ( page . locator ( '.pagination .page-item:has(button:has-text("2"))' ) ) . toHaveClass ( / a c t i v e / ) ;
157128 } ) ;
@@ -162,17 +133,13 @@ test.describe('Pagination', () => {
162133 const testUser = generateUniqueUser ( ) ;
163134 const token = await registerUserViaAPI ( request , testUser ) ;
164135 await createManyArticles ( request , token , 15 , uniqueTag ) ;
165-
166136 // Login as the user who created the articles (session isolation)
167137 await login ( page , testUser . email , testUser . password ) ;
168-
169138 // Go directly to page 2 of the tag
170139 await page . goto ( `/tag/${ uniqueTag } ?page=2` ) ;
171- await page . waitForSelector ( '.article-preview' , { timeout : 15000 } ) ;
172-
140+ await page . waitForSelector ( '.article-preview' , { timeout : 2000 } ) ;
173141 // Page 2 should be active
174142 await expect ( page . locator ( '.pagination .page-item:has(button:has-text("2"))' ) ) . toHaveClass ( / a c t i v e / ) ;
175-
176143 // URL should have page=2
177144 const url = new URL ( page . url ( ) ) ;
178145 expect ( url . searchParams . get ( 'page' ) ) . toBe ( '2' ) ;
@@ -181,22 +148,17 @@ test.describe('Pagination', () => {
181148 test ( 'pagination URL preserves feed=following parameter' , async ( { page } ) => {
182149 const user = generateUniqueUser ( ) ;
183150 await register ( page , user . username , user . email , user . password ) ;
184-
185151 // Your Feed shows articles from users you FOLLOW (not your own articles)
186152 // Just verify that if pagination exists on Your Feed, the URL is correct
187153 await page . goto ( '/?feed=following' ) ;
188-
189154 // Wait for the page to load (might be empty or have articles)
190- await page . waitForSelector ( '.article-preview, .empty-feed-message' , { timeout : 15000 } ) ;
191-
155+ await page . waitForSelector ( '.article-preview, .empty-feed-message' , { timeout : 2000 } ) ;
192156 // Check if pagination exists (depends on followed users having 11+ articles)
193157 const page2Button = page . locator ( '.pagination button:has-text("2")' ) ;
194158 const hasPage2 = await page2Button . isVisible ( ) . catch ( ( ) => false ) ;
195-
196159 if ( hasPage2 ) {
197160 // Click page 2
198161 await page . click ( '.pagination button:has-text("2")' ) ;
199-
200162 // URL should preserve feed param and add page
201163 await expect ( page ) . toHaveURL ( '/?feed=following&page=2' ) ;
202164 } else {
@@ -211,20 +173,15 @@ test.describe('Pagination', () => {
211173 const testUser = generateUniqueUser ( ) ;
212174 const token = await registerUserViaAPI ( request , testUser ) ;
213175 await createManyArticles ( request , token , 15 , uniqueTag ) ;
214-
215176 // Login as the user who created the articles (session isolation)
216177 await login ( page , testUser . email , testUser . password ) ;
217-
218178 // Navigate to our tag
219179 await page . goto ( `/tag/${ uniqueTag } ` ) ;
220- await page . waitForSelector ( '.article-preview' , { timeout : 15000 } ) ;
221-
180+ await page . waitForSelector ( '.article-preview' , { timeout : 2000 } ) ;
222181 // Should have pagination
223- await expect ( page . locator ( '.pagination button:has-text("2")' ) ) . toBeVisible ( { timeout : 15000 } ) ;
224-
182+ await expect ( page . locator ( '.pagination button:has-text("2")' ) ) . toBeVisible ( { timeout : 2000 } ) ;
225183 // Click page 2
226184 await page . click ( '.pagination button:has-text("2")' ) ;
227-
228185 // Verify URL contains the tag and page parameter
229186 const url = new URL ( page . url ( ) ) ;
230187 expect ( decodeURIComponent ( url . pathname ) ) . toBe ( `/tag/${ uniqueTag } ` ) ;
@@ -237,27 +194,21 @@ test.describe('Pagination', () => {
237194 const testUser = generateUniqueUser ( ) ;
238195 const token = await registerUserViaAPI ( request , testUser ) ;
239196 await createManyArticles ( request , token , 15 , uniqueTag ) ;
240-
241197 // Login as the user who created the articles (session isolation)
242198 await login ( page , testUser . email , testUser . password ) ;
243-
244199 // Navigate to our tag
245200 await page . goto ( `/tag/${ uniqueTag } ` ) ;
246- await page . waitForSelector ( '.article-preview' , { timeout : 15000 } ) ;
247-
201+ await page . waitForSelector ( '.article-preview' , { timeout : 2000 } ) ;
248202 // Should have pagination
249- await expect ( page . locator ( '.pagination button:has-text("2")' ) ) . toBeVisible ( { timeout : 15000 } ) ;
250-
203+ await expect ( page . locator ( '.pagination button:has-text("2")' ) ) . toBeVisible ( { timeout : 2000 } ) ;
251204 // Go to page 2
252205 await page . click ( '.pagination button:has-text("2")' ) ;
253206 await expect ( page ) . toHaveURL ( new RegExp ( `/tag/${ uniqueTag } \\?page=2` ) ) ;
254-
255207 // Click Global Feed and wait for URL to change to root path
256208 await page . click ( '.nav-link:has-text("Global Feed")' ) ;
257209 await expect ( page ) . toHaveURL ( '/' ) ;
258-
259210 // Verify articles loaded
260- await page . waitForSelector ( '.article-preview' , { timeout : 10000 } ) ;
211+ await page . waitForSelector ( '.article-preview' , { timeout : 2000 } ) ;
261212 } ) ;
262213
263214 test ( 'tag pagination shows correct articles per page' , async ( { page, request } ) => {
@@ -266,36 +217,27 @@ test.describe('Pagination', () => {
266217 const testUser = generateUniqueUser ( ) ;
267218 const token = await registerUserViaAPI ( request , testUser ) ;
268219 await createManyArticles ( request , token , 15 , uniqueTag ) ;
269-
270220 // Login as the user who created the articles (session isolation)
271221 await login ( page , testUser . email , testUser . password ) ;
272-
273222 // Navigate to our tag
274223 await page . goto ( `/tag/${ uniqueTag } ` ) ;
275- await page . waitForSelector ( '.article-preview' , { timeout : 15000 } ) ;
276-
224+ await page . waitForSelector ( '.article-preview' , { timeout : 2000 } ) ;
277225 // Should have pagination (15 articles = 2 pages)
278- await expect ( page . locator ( '.pagination button:has-text("2")' ) ) . toBeVisible ( { timeout : 15000 } ) ;
279-
226+ await expect ( page . locator ( '.pagination button:has-text("2")' ) ) . toBeVisible ( { timeout : 2000 } ) ;
280227 // First page should show 10 articles
281228 const articlesOnPage1 = await page . locator ( '.article-preview' ) . count ( ) ;
282229 expect ( articlesOnPage1 ) . toBe ( 10 ) ;
283-
284230 // Click page 2
285231 await page . click ( '.pagination button:has-text("2")' ) ;
286-
287232 // Wait for page 2 to be active (Angular routing/rendering delay)
288233 await expect ( page . locator ( '.pagination .page-item:has(button:has-text("2"))' ) ) . toHaveClass ( / a c t i v e / , {
289- timeout : 10000 ,
234+ timeout : 2000 ,
290235 } ) ;
291- await page . waitForSelector ( '.article-preview' , { timeout : 10000 } ) ;
292-
236+ await page . waitForSelector ( '.article-preview' , { timeout : 2000 } ) ;
293237 // URL should show ?page=2
294238 await expect ( page ) . toHaveURL ( new RegExp ( `/tag/${ uniqueTag } \\?page=2` ) ) ;
295-
296239 // Small wait for Angular to finish rendering the new page
297240 await page . waitForTimeout ( 500 ) ;
298-
299241 // Second page should have 5 articles (15 - 10 = 5)
300242 const articlesOnPage2 = await page . locator ( '.article-preview' ) . count ( ) ;
301243 expect ( articlesOnPage2 ) . toBe ( 5 ) ;
0 commit comments