Skip to content

Commit 4824d5d

Browse files
committed
Fix Playwright strict mode violations in E2E tests
- Use .first() for selectors that may match multiple elements - Scope selectors to specific containers (modal, footer, table) - Use role-based selectors for tab navigation in download modal - Fix contact form, comparison page, download modal, homepage, and navigation tests
1 parent fa11ceb commit 4824d5d

File tree

5 files changed

+49
-38
lines changed

5 files changed

+49
-38
lines changed

frontend/e2e/comparison-page.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ test.describe('Comparison Page', () => {
2222
});
2323

2424
test('should display CryFS in the comparison', async ({ page }) => {
25-
await expect(page.getByText('CryFS')).toBeVisible();
25+
// CryFS should be in the comparison table
26+
const table = page.locator('table');
27+
await expect(table.getByText('CryFS').first()).toBeVisible();
2628
});
2729

2830
test('should display alternative encryption tools', async ({ page }) => {

frontend/e2e/contact-form.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ test.describe('Contact Form Flow', () => {
6565
await sendButton.click();
6666

6767
// Should show success message
68-
await expect(page.getByText(/thank you/i)).toBeVisible();
68+
await expect(page.getByText(/thank you/i).first()).toBeVisible();
6969
});
7070

7171
test('should allow submission without email', async ({ page }) => {
@@ -81,7 +81,7 @@ test.describe('Contact Form Flow', () => {
8181
await sendButton.click();
8282

8383
// Should show success message
84-
await expect(page.getByText(/thank you/i)).toBeVisible();
84+
await expect(page.getByText(/thank you/i).first()).toBeVisible();
8585
});
8686

8787
test('should include email in submission when provided', async ({ page }) => {
@@ -102,7 +102,7 @@ test.describe('Contact Form Flow', () => {
102102
await sendButton.click();
103103

104104
// Wait for request to complete
105-
await expect(page.getByText(/thank you/i)).toBeVisible();
105+
await expect(page.getByText(/thank you/i).first()).toBeVisible();
106106

107107
expect(requestBody.email).toBe('test@example.com');
108108
expect(requestBody.message).toBe('Test message');

frontend/e2e/download-modal.spec.ts

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,62 +9,69 @@ test.describe('Download Modal Flow', () => {
99
await expect(modal).toBeVisible();
1010

1111
// Should show download header
12-
await expect(page.getByText(/download cryfs/i)).toBeVisible();
12+
await expect(modal.getByText(/download cryfs/i)).toBeVisible();
1313
});
1414

1515
test('should display OS selection tabs', async ({ page }) => {
1616
await page.goto('/#download');
1717

18-
await expect(page.getByText('Ubuntu')).toBeVisible();
19-
await expect(page.getByText('Debian')).toBeVisible();
20-
await expect(page.getByText('Other')).toBeVisible();
18+
const modal = page.locator('.modal');
19+
// Check for tab elements with OS names
20+
await expect(modal.getByRole('tab', { name: /ubuntu/i })).toBeVisible();
21+
await expect(modal.getByRole('tab', { name: /debian/i })).toBeVisible();
22+
await expect(modal.getByRole('tab', { name: /other/i })).toBeVisible();
2123
});
2224

2325
test('should show Ubuntu instructions by default', async ({ page }) => {
2426
await page.goto('/#download');
2527

28+
const modal = page.locator('.modal');
2629
// Ubuntu Easy Install should be visible
27-
await expect(page.getByText('Easy Install')).toBeVisible();
28-
await expect(page.getByText(/ubuntu 17.04 and later/i)).toBeVisible();
29-
await expect(page.getByText('sudo apt install cryfs')).toBeVisible();
30+
await expect(modal.getByText('Easy Install').first()).toBeVisible();
31+
await expect(modal.getByText(/ubuntu 17.04 and later/i)).toBeVisible();
32+
await expect(modal.getByText('sudo apt install cryfs').first()).toBeVisible();
3033
});
3134

3235
test('should switch to Debian tab', async ({ page }) => {
3336
await page.goto('/#download');
3437

35-
await page.getByText('Debian').click();
38+
const modal = page.locator('.modal');
39+
await modal.getByRole('tab', { name: /debian/i }).click();
3640

3741
// Debian instructions should be visible
38-
await expect(page.getByText(/debian stretch and later/i)).toBeVisible();
42+
await expect(modal.getByText(/debian stretch and later/i)).toBeVisible();
3943
});
4044

4145
test('should switch to Other tab and show macOS instructions', async ({ page }) => {
4246
await page.goto('/#download');
4347

44-
await page.getByText('Other').click();
48+
const modal = page.locator('.modal');
49+
await modal.getByRole('tab', { name: /other/i }).click();
4550

4651
// macOS instructions should be visible
47-
await expect(page.getByText('Mac OS X')).toBeVisible();
48-
await expect(page.getByText('brew install --cask macfuse')).toBeVisible();
49-
await expect(page.getByText('brew install cryfs/tap/cryfs')).toBeVisible();
52+
await expect(modal.getByText('Mac OS X').first()).toBeVisible();
53+
await expect(modal.getByText('brew install --cask macfuse').first()).toBeVisible();
54+
await expect(modal.getByText('brew install cryfs/tap/cryfs').first()).toBeVisible();
5055
});
5156

5257
test('should show Windows instructions in Other tab', async ({ page }) => {
5358
await page.goto('/#download');
5459

55-
await page.getByText('Other').click();
60+
const modal = page.locator('.modal');
61+
await modal.getByRole('tab', { name: /other/i }).click();
5662

5763
// Windows instructions should be visible
58-
await expect(page.getByText('Windows')).toBeVisible();
59-
await expect(page.getByText(/windows support is highly experimental/i)).toBeVisible();
64+
await expect(modal.getByText('Windows').first()).toBeVisible();
65+
await expect(modal.getByText(/windows support is highly experimental/i)).toBeVisible();
6066
});
6167

6268
test('should have DokanY download link', async ({ page }) => {
6369
await page.goto('/#download');
6470

65-
await page.getByText('Other').click();
71+
const modal = page.locator('.modal');
72+
await modal.getByRole('tab', { name: /other/i }).click();
6673

67-
const dokanLink = page.getByRole('link', { name: /dokany/i });
74+
const dokanLink = modal.getByRole('link', { name: /dokany/i });
6875
await expect(dokanLink).toBeVisible();
6976
await expect(dokanLink).toHaveAttribute('href', 'https://github.com/dokan-dev/dokany/releases');
7077
});
@@ -73,21 +80,23 @@ test.describe('Download Modal Flow', () => {
7380
await page.goto('/#download');
7481

7582
// Modal should be visible
76-
await expect(page.locator('.modal')).toBeVisible();
83+
const modal = page.locator('.modal');
84+
await expect(modal).toBeVisible();
7785

7886
// Click close button
79-
const closeButton = page.getByRole('button', { name: /close/i });
87+
const closeButton = modal.getByRole('button', { name: /close/i });
8088
await closeButton.click();
8189

8290
// Modal should be hidden
83-
await expect(page.locator('.modal')).not.toBeVisible();
91+
await expect(modal).not.toBeVisible();
8492
});
8593

8694
test('should update URL hash when modal closes', async ({ page }) => {
8795
await page.goto('/#download');
8896

97+
const modal = page.locator('.modal');
8998
// Close modal
90-
const closeButton = page.getByRole('button', { name: /close/i });
99+
const closeButton = modal.getByRole('button', { name: /close/i });
91100
await closeButton.click();
92101

93102
// URL should no longer have #download
@@ -97,19 +106,18 @@ test.describe('Download Modal Flow', () => {
97106
test('should display OS logos', async ({ page }) => {
98107
await page.goto('/#download');
99108

100-
await expect(page.getByAltText('Ubuntu')).toBeVisible();
101-
await expect(page.getByAltText('Debian')).toBeVisible();
102-
await expect(page.getByAltText('Other')).toBeVisible();
109+
const modal = page.locator('.modal');
110+
await expect(modal.getByAltText('Ubuntu')).toBeVisible();
111+
await expect(modal.getByAltText('Debian')).toBeVisible();
112+
await expect(modal.getByAltText('Other')).toBeVisible();
103113
});
104114

105115
test('should link to GitHub releases for older versions', async ({ page }) => {
106116
await page.goto('/#download');
107117

108-
const releasesLink = page.getByRole('link', { name: /here/i }).filter({
109-
has: page.locator('[href*="github.com/cryfs/cryfs/releases"]'),
110-
});
111-
112-
await expect(releasesLink).toBeVisible();
118+
const modal = page.locator('.modal');
119+
const releasesLink = modal.locator('a[href*="github.com/cryfs/cryfs/releases"]');
120+
await expect(releasesLink.first()).toBeVisible();
113121
});
114122

115123
test('should open modal from download link on homepage', async ({ page }) => {
@@ -120,7 +128,8 @@ test.describe('Download Modal Flow', () => {
120128
await downloadLink.click();
121129

122130
// Modal should appear
123-
await expect(page.locator('.modal')).toBeVisible();
124-
await expect(page.getByText(/download cryfs/i)).toBeVisible();
131+
const modal = page.locator('.modal');
132+
await expect(modal).toBeVisible();
133+
await expect(modal.getByText(/download cryfs/i)).toBeVisible();
125134
});
126135
});

frontend/e2e/homepage.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ test.describe('Homepage', () => {
3333
test('should display the footer', async ({ page }) => {
3434
const footer = page.locator('footer');
3535
await expect(footer).toBeVisible();
36-
await expect(page.getByText(/Sebastian Messmer/)).toBeVisible();
36+
await expect(footer.getByText(/Sebastian Messmer/)).toBeVisible();
3737
});
3838

3939
test('should display legal notice link in footer', async ({ page }) => {

frontend/e2e/navigation.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ test.describe('Navigation', () => {
102102
// Footer should still be visible
103103
const footer = page.locator('footer');
104104
await expect(footer).toBeVisible();
105-
await expect(page.getByText(/Sebastian Messmer/)).toBeVisible();
105+
await expect(footer.getByText(/Sebastian Messmer/)).toBeVisible();
106106
});
107107
});
108108

0 commit comments

Comments
 (0)