forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
1import { expect, test } from './test-utils'
2
3test.describe('npmjs.com URL Compatibility', () => {
4 test.describe('Package Pages', () => {
5 test('/package/vue → package page', async ({ page, goto }) => {
6 await goto('/package/vue', { waitUntil: 'domcontentloaded' })
7
8 // Should show package name
9 await expect(page.locator('h1')).toContainText('vue')
10 // Should have version badge
11 await expect(page.locator('main header').locator('text=/v\\d+\\.\\d+/')).toBeVisible()
12 })
13
14 test('/package/@nuxt/kit → scoped package page', async ({ page, goto }) => {
15 await goto('/package/@nuxt/kit', { waitUntil: 'domcontentloaded' })
16
17 // Should show scoped package name
18 await expect(page.locator('h1')).toContainText('@nuxt/kit')
19 })
20
21 test('/package/vue/v/3.5.27 → specific version', async ({ page, goto }) => {
22 await goto('/package/vue/v/3.5.27', { waitUntil: 'domcontentloaded' })
23
24 // Should show package name
25 await expect(page.locator('h1')).toContainText('vue')
26 // Should show the specific version
27 await expect(page.locator('text=v3.5.27')).toBeVisible()
28 })
29
30 test('/package/@nuxt/kit/v/3.20.0 → scoped package specific version', async ({
31 page,
32 goto,
33 }) => {
34 await goto('/package/@nuxt/kit/v/3.20.0', { waitUntil: 'domcontentloaded' })
35
36 // Should show scoped package name
37 await expect(page.locator('h1')).toContainText('@nuxt/kit')
38 // Should show the specific version (or "not latest" indicator)
39 await expect(page.locator('text=v3.20.0').first()).toBeVisible()
40 })
41
42 test('/package/nonexistent-pkg-12345 → 404 handling', async ({ page, goto }) => {
43 await goto('/package/nonexistent-pkg-12345', { waitUntil: 'domcontentloaded' })
44
45 // Should show error state - look for the heading specifically
46 await expect(page.getByRole('heading', { name: /not found/i })).toBeVisible()
47 })
48 })
49
50 test.describe('Search Pages', () => {
51 test('/search?q=vue → search results', async ({ page, goto }) => {
52 await goto('/search?q=vue', { waitUntil: 'domcontentloaded' })
53
54 // Should show search input with query
55 await expect(page.locator('input[type="search"]')).toHaveValue('vue')
56 // Should show results count
57 await expect(page.locator('text=/found \\d+/i')).toBeVisible()
58 })
59
60 test('/search?q=keywords:framework → keyword search', async ({ page, goto }) => {
61 await goto('/search?q=keywords:framework', { waitUntil: 'domcontentloaded' })
62
63 // Should show search input with query
64 await expect(page.locator('input[type="search"]')).toHaveValue('keywords:framework')
65 // Should show results
66 await expect(page.locator('text=/found \\d+/i')).toBeVisible()
67 })
68
69 test('/search → empty search page', async ({ page, goto }) => {
70 await goto('/search', { waitUntil: 'domcontentloaded' })
71
72 // Should show empty state prompt
73 await expect(page.locator('text=/start typing/i')).toBeVisible()
74 })
75 })
76
77 test.describe('User Profile Pages', () => {
78 test('/~qwerzl → user profile', async ({ page, goto }) => {
79 await goto('/~qwerzl', { waitUntil: 'hydration' })
80
81 // Should show username
82 await expect(page.locator('h1')).toContainText('~qwerzl')
83
84 await expect(page.locator('text=/\\d+\\s+public\\s+package/i').first()).toBeVisible({
85 timeout: 15000,
86 })
87 })
88
89 test('/~nonexistent-user-12345 → empty user handling', async ({ page, goto }) => {
90 await goto('/~nonexistent-user-12345', { waitUntil: 'domcontentloaded' })
91
92 // Should show username in header
93 await expect(page.locator('h1')).toContainText('~nonexistent-user-12345')
94 // Should show empty state message
95 await expect(page.getByText('No public packages found for')).toBeVisible()
96 })
97 })
98
99 test.describe('Organization Pages', () => {
100 test('/org/nuxt → organization page', async ({ page, goto }) => {
101 await goto('/org/nuxt', { waitUntil: 'domcontentloaded' })
102
103 // Should show org name
104 await expect(page.locator('h1')).toContainText('@nuxt')
105 // Should show packages heading
106 await expect(page.getByRole('heading', { name: 'Packages' })).toBeVisible()
107 })
108
109 test('/org/nonexistent-org-12345 → 404 handling', async ({ page, goto }) => {
110 await goto('/org/nonexistent-org-12345', { waitUntil: 'domcontentloaded' })
111
112 // Should show 404 error page
113 await expect(page.locator('h1')).toContainText('Organization not found')
114 })
115 })
116
117 test.describe('Edge Cases', () => {
118 test('package name with dots: /package/lodash.merge', async ({ page, goto }) => {
119 await goto('/package/lodash.merge', { waitUntil: 'domcontentloaded' })
120
121 await expect(page.locator('h1')).toContainText('lodash.merge')
122 })
123
124 test('package name with hyphens: /package/is-odd', async ({ page, goto }) => {
125 await goto('/package/is-odd', { waitUntil: 'domcontentloaded' })
126
127 await expect(page.locator('h1')).toContainText('is-odd')
128 })
129
130 test('scoped package with hyphens: /package/@types/node', async ({ page, goto }) => {
131 await goto('/package/@types/node', { waitUntil: 'domcontentloaded' })
132
133 await expect(page.locator('h1')).toContainText('@types/node')
134 })
135 })
136})