|
3 | 3 | * Tests for the contact page and form |
4 | 4 | */ |
5 | 5 | import { test, expect } from '@playwright/test' |
6 | | -import { TEST_URLS } from '../../fixtures/test-data' |
| 6 | +import { TEST_URLS } from '@test/e2e/fixtures/test-data' |
| 7 | +import { setupConsoleErrorChecker } from '@test/e2e/helpers/console-errors' |
7 | 8 |
|
8 | 9 | test.describe('Contact Page', () => { |
9 | 10 | test.beforeEach(async ({ page }) => { |
10 | 11 | await page.goto(TEST_URLS.contact) |
11 | 12 | }) |
12 | 13 |
|
13 | | - test.skip('@wip page loads with correct title', async ({ page }) => { |
14 | | - // Expected: Page title should include "Contact" |
15 | | - // Actual: Unknown - needs testing |
| 14 | + test('@ready page loads with correct title', async ({ page }) => { |
16 | 15 | await expect(page).toHaveTitle(/Contact/) |
17 | 16 | }) |
18 | 17 |
|
19 | | - test.skip('@wip hero section displays', async ({ page }) => { |
20 | | - // Expected: Should show hero with heading and description |
21 | | - // Actual: Unknown - needs testing |
22 | | - await expect(page.locator('h1')).toContainText(/Let's Build Something Amazing/) |
| 18 | + test('@ready hero section displays', async ({ page }) => { |
| 19 | + const heroHeading = page.locator('h1') |
| 20 | + await expect(heroHeading).toContainText(/Let's Build Something Amazing/) |
23 | 21 | }) |
24 | 22 |
|
25 | | - test.skip('@wip contact form is visible', async ({ page }) => { |
26 | | - // Expected: Form should be visible with all fields |
27 | | - // Actual: Unknown - needs testing |
28 | | - await expect(page.locator('#contactForm')).toBeVisible() |
| 23 | + test('@ready contact form is visible', async ({ page }) => { |
| 24 | + const form = page.locator('#contactForm') |
| 25 | + await expect(form).toBeVisible() |
29 | 26 | }) |
30 | 27 |
|
31 | | - test.skip('@wip all form fields are present', async ({ page }) => { |
32 | | - // Expected: Should have name, email, company, phone, etc. |
33 | | - // Actual: Unknown - needs testing |
| 28 | + test('@ready required form fields are present', async ({ page }) => { |
| 29 | + // Required fields: name, email, message |
34 | 30 | await expect(page.locator('#name')).toBeVisible() |
35 | 31 | await expect(page.locator('#email')).toBeVisible() |
| 32 | + await expect(page.locator('#message')).toBeVisible() |
| 33 | + }) |
| 34 | + |
| 35 | + test('@ready optional form fields are present', async ({ page }) => { |
| 36 | + // Optional fields: company, phone, project type, budget, timeline |
36 | 37 | await expect(page.locator('#company')).toBeVisible() |
37 | 38 | await expect(page.locator('#phone')).toBeVisible() |
38 | | - await expect(page.locator('#subject')).toBeVisible() |
39 | | - await expect(page.locator('#message')).toBeVisible() |
| 39 | + await expect(page.locator('#project_type')).toBeVisible() |
| 40 | + await expect(page.locator('#budget')).toBeVisible() |
| 41 | + await expect(page.locator('#timeline')).toBeVisible() |
| 42 | + }) |
| 43 | + |
| 44 | + test('@ready GDPR consent checkbox present', async ({ page }) => { |
| 45 | + // Contact form uses id="contact-gdpr-consent" |
| 46 | + const gdprConsent = page.locator('#contact-gdpr-consent') |
| 47 | + await expect(gdprConsent).toBeVisible() |
40 | 48 | }) |
41 | 49 |
|
42 | | - test.skip('@wip GDPR consent checkbox present', async ({ page }) => { |
43 | | - // Expected: Should have required GDPR consent checkbox |
44 | | - // Actual: Unknown - needs testing |
45 | | - await expect(page.locator('#gdpr-consent')).toBeVisible() |
| 50 | + test('@ready contact information sidebar displays', async ({ page }) => { |
| 51 | + // The sidebar has "Get In Touch" heading |
| 52 | + const sidebar = page.locator('text=Get In Touch') |
| 53 | + await expect(sidebar).toBeVisible() |
46 | 54 | }) |
47 | 55 |
|
48 | | - test.skip('@wip contact information sidebar displays', async ({ page }) => { |
49 | | - // Expected: Should show response time and expertise info |
50 | | - // Actual: Unknown - needs testing |
51 | | - await expect(page.locator('text=Response Time')).toBeVisible() |
52 | | - await expect(page.locator('text=Our Expertise')).toBeVisible() |
| 56 | + test('@ready submit button is present', async ({ page }) => { |
| 57 | + const submitButton = page.locator('button[type="submit"]') |
| 58 | + await expect(submitButton).toBeVisible() |
| 59 | + await expect(submitButton).toContainText(/Send Project Details/) |
53 | 60 | }) |
54 | 61 |
|
55 | | - test.skip('@wip submit button is present', async ({ page }) => { |
56 | | - // Expected: Submit button should be visible |
57 | | - // Actual: Unknown - needs testing |
58 | | - await expect(page.locator('button[type="submit"]')).toBeVisible() |
| 62 | + test('@ready form has proper labels and accessibility', async ({ page }) => { |
| 63 | + // Check that required inputs have associated labels |
| 64 | + const nameLabel = page.locator('label[for="name"]') |
| 65 | + await expect(nameLabel).toBeVisible() |
| 66 | + await expect(nameLabel).toContainText(/Full Name/) |
| 67 | + |
| 68 | + const emailLabel = page.locator('label[for="email"]') |
| 69 | + await expect(emailLabel).toBeVisible() |
| 70 | + await expect(emailLabel).toContainText(/Email/) |
| 71 | + |
| 72 | + const messageLabel = page.locator('label[for="message"]') |
| 73 | + await expect(messageLabel).toBeVisible() |
| 74 | + await expect(messageLabel).toContainText(/Project Description/) |
| 75 | + }) |
| 76 | + |
| 77 | + test('@ready form sections are properly organized', async ({ page }) => { |
| 78 | + // Check for section headings - use h3 selector to avoid matching text in paragraphs |
| 79 | + await expect(page.locator('h3').filter({ hasText: 'Contact Information' })).toBeVisible() |
| 80 | + await expect(page.locator('h3').filter({ hasText: 'Project Details' })).toBeVisible() |
| 81 | + await expect(page.locator('h3').filter({ hasText: 'Project Files' })).toBeVisible() |
59 | 82 | }) |
60 | 83 |
|
61 | | - test.skip('@wip form has proper labels and accessibility', async ({ page }) => { |
62 | | - // Expected: All inputs should have associated labels |
63 | | - // Actual: Unknown - needs testing |
64 | | - const nameInput = page.locator('#name') |
65 | | - const label = await nameInput.evaluate((el) => { |
66 | | - const id = el.getAttribute('id') |
67 | | - return document.querySelector(`label[for="${id}"]`)?.textContent |
68 | | - }) |
69 | | - expect(label).toBeTruthy() |
| 84 | + test('@ready data retention notice is displayed', async ({ page }) => { |
| 85 | + // Check for GDPR-compliant data retention notice |
| 86 | + await expect(page.locator('text=Data Retention')).toBeVisible() |
| 87 | + await expect(page.locator('text=Your Rights')).toBeVisible() |
70 | 88 | }) |
71 | 89 |
|
72 | | - test.skip('@wip responsive: mobile view renders correctly', async ({ page }) => { |
73 | | - // Expected: Contact page should be fully functional on mobile |
74 | | - // Actual: Unknown - needs testing |
| 90 | + test('@ready responsive: mobile view renders correctly', async ({ page }) => { |
75 | 91 | await page.setViewportSize({ width: 375, height: 667 }) |
76 | 92 | await expect(page.locator('#contactForm')).toBeVisible() |
| 93 | + await expect(page.locator('h1')).toBeVisible() |
| 94 | + }) |
| 95 | + |
| 96 | + test('@ready page has no console errors', async ({ page }) => { |
| 97 | + const errorChecker = setupConsoleErrorChecker(page) |
| 98 | + await page.goto(TEST_URLS.contact) |
| 99 | + await page.waitForLoadState('networkidle') |
| 100 | + expect(errorChecker.getFiltered404s().length).toBe(0) |
77 | 101 | }) |
78 | 102 | }) |
0 commit comments