/**
* Mobile Responsiveness Test for HVAC Plugin UX Enhancements
*
* Simplified mobile testing focusing on key responsiveness features
*/
import { test, expect } from '@playwright/test';
const STAGING_URL = 'https://upskill-staging.measurequick.com';
// Test responsive breakpoints
test.describe('Mobile Responsiveness', () => {
test('Mobile login page layout (iPhone viewport)', async ({ page }) => {
test.setTimeout(20000);
// Set mobile viewport
await page.setViewportSize({ width: 375, height: 667 });
await page.goto(`${STAGING_URL}/community-login`);
await page.waitForLoadState('networkidle');
// Check login form is properly sized for mobile
const loginForm = page.locator('#hvac_community_loginform');
await expect(loginForm).toBeVisible();
// Verify mobile-optimized form elements
const usernameField = page.locator('#user_login');
const passwordField = page.locator('#user_pass');
const submitButton = page.locator('#wp-submit');
await expect(usernameField).toBeVisible();
await expect(passwordField).toBeVisible();
await expect(submitButton).toBeVisible();
// Check touch target sizes (minimum 44px for iOS)
const submitBox = await submitButton.boundingBox();
expect(submitBox?.height).toBeGreaterThanOrEqual(40);
// Test form field focus states work on mobile
await usernameField.focus();
await passwordField.focus();
// Take screenshot for visual verification
await page.screenshot({ path: `test-results/mobile-login-375x667.png` });
});
test('Mobile dashboard layout and navigation', async ({ page }) => {
test.setTimeout(30000);
// Set mobile viewport
await page.setViewportSize({ width: 375, height: 667 });
// Login first
await page.goto(`${STAGING_URL}/community-login`);
await page.fill('#user_login', 'test_trainer');
await page.fill('#user_pass', 'Test123!');
await page.click('#wp-submit');
await page.waitForLoadState('networkidle');
// Verify we're on dashboard
await expect(page).toHaveURL(/hvac-dashboard/);
// Check dashboard layout adapts to mobile
const dashboard = page.locator('.hvac-dashboard-wrapper');
await expect(dashboard).toBeVisible();
// Test mobile navigation if present
const mobileNavToggle = page.locator('.hvac-mobile-nav-toggle');
if (await mobileNavToggle.isVisible()) {
await mobileNavToggle.click();
const mobileNav = page.locator('.hvac-mobile-nav');
await expect(mobileNav).toHaveClass(/open/);
// Test navigation links work
const navLinks = page.locator('.hvac-mobile-nav a');
const navCount = await navLinks.count();
expect(navCount).toBeGreaterThan(0);
}
// Check stats cards stack properly on mobile
const statCards = page.locator('.hvac-stat-card');
const statCount = await statCards.count();
if (statCount > 0) {
// Verify cards are visible and properly sized
for (let i = 0; i < Math.min(statCount, 3); i++) {
await expect(statCards.nth(i)).toBeVisible();
}
}
// Test touch scrolling works
await page.evaluate(() => window.scrollTo(0, 200));
await page.waitForTimeout(500);
// Take screenshot
await page.screenshot({ path: `test-results/mobile-dashboard-375x667.png` });
});
test('Toast notifications positioning on mobile', async ({ page }) => {
test.setTimeout(25000);
// Set mobile viewport
await page.setViewportSize({ width: 375, height: 667 });
// Login
await page.goto(`${STAGING_URL}/community-login`);
await page.fill('#user_login', 'test_trainer');
await page.fill('#user_pass', 'Test123!');
await page.click('#wp-submit');
await page.waitForLoadState('networkidle');
// Go to certificate reports to trigger potential notifications
await page.goto(`${STAGING_URL}/certificate-reports`);
await page.waitForLoadState('networkidle');
// Inject test toast to verify mobile positioning
await page.evaluate(() => {
// Create toast container if it doesn't exist
if (!document.querySelector('.hvac-toast-container')) {
const container = document.createElement('div');
container.className = 'hvac-toast-container';
container.style.cssText = `
position: fixed;
top: 10px;
right: 10px;
left: 10px;
z-index: 10000;
display: flex;
flex-direction: column;
gap: 10px;
max-width: none;
pointer-events: none;
`;
document.body.appendChild(container);
}
// Create a test toast
const toast = document.createElement('div');
toast.className = 'hvac-toast success show';
toast.style.cssText = `
background: white;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
padding: 16px 20px;
pointer-events: all;
transform: translateX(0);
border-left: 4px solid #10b981;
display: flex;
align-items: flex-start;
gap: 12px;
max-width: 100%;
word-wrap: break-word;
`;
toast.innerHTML = `
✓
Success
Mobile toast notification test - this is a longer message to test wrapping
`;
const container = document.querySelector('.hvac-toast-container');
if (container) {
container.appendChild(toast);
}
});
await page.waitForTimeout(1000);
// Check if toast is visible and properly positioned
const toast = page.locator('.hvac-toast');
await expect(toast).toBeVisible();
// Verify toast doesn't overflow viewport
const toastBox = await toast.boundingBox();
const viewport = page.viewportSize();
if (toastBox && viewport) {
expect(toastBox.x + toastBox.width).toBeLessThanOrEqual(viewport.width);
expect(toastBox.y).toBeGreaterThanOrEqual(0);
}
// Take screenshot
await page.screenshot({ path: `test-results/mobile-toast-375x667.png` });
});
test('Form interaction on mobile devices', async ({ page }) => {
test.setTimeout(25000);
// Set mobile viewport
await page.setViewportSize({ width: 375, height: 667 });
// Login
await page.goto(`${STAGING_URL}/community-login`);
await page.fill('#user_login', 'test_trainer');
await page.fill('#user_pass', 'Test123!');
await page.click('#wp-submit');
await page.waitForLoadState('networkidle');
// Go to create event page to test forms
await page.goto(`${STAGING_URL}/manage-event`);
await page.waitForLoadState('networkidle');
// Test form field interactions
const titleField = page.locator('#event_title');
if (await titleField.isVisible()) {
// Check field is properly sized for mobile
const fieldBox = await titleField.boundingBox();
expect(fieldBox?.height).toBeGreaterThanOrEqual(40);
// Test touch interaction
await titleField.tap();
await titleField.fill('Mobile Test Event');
const value = await titleField.inputValue();
expect(value).toBe('Mobile Test Event');
}
// Check form buttons are touch-friendly
const buttons = page.locator('button, input[type="submit"]');
const buttonCount = await buttons.count();
if (buttonCount > 0) {
const button = buttons.first();
if (await button.isVisible()) {
const buttonBox = await button.boundingBox();
expect(buttonBox?.height).toBeGreaterThanOrEqual(40);
}
}
// Take screenshot
await page.screenshot({ path: `test-results/mobile-form-375x667.png` });
});
test('Responsive breakpoints verification', async ({ page }) => {
test.setTimeout(35000);
const breakpoints = [
{ name: 'Mobile-Small', width: 320, height: 568 },
{ name: 'Mobile-Medium', width: 375, height: 667 },
{ name: 'Tablet-Portrait', width: 768, height: 1024 },
];
for (const breakpoint of breakpoints) {
// Set viewport
await page.setViewportSize({ width: breakpoint.width, height: breakpoint.height });
// Login
await page.goto(`${STAGING_URL}/community-login`);
await page.fill('#user_login', 'test_trainer');
await page.fill('#user_pass', 'Test123!');
await page.click('#wp-submit');
await page.waitForLoadState('networkidle');
// Check dashboard layout
await expect(page).toHaveURL(/hvac-dashboard/);
// Verify content is visible and accessible
const mainContent = page.locator('.hvac-dashboard-wrapper, .entry-content');
await expect(mainContent).toBeVisible();
// Check navigation is appropriate for screen size
if (breakpoint.width <= 767) {
// Mobile: navigation should adapt
const nav = page.locator('.hvac-dashboard-nav');
await expect(nav).toBeVisible();
} else {
// Tablet/Desktop: should see regular nav
const desktopNav = page.locator('.hvac-dashboard-nav');
await expect(desktopNav).toBeVisible();
}
// Take screenshot
await page.screenshot({
path: `test-results/responsive-${breakpoint.name}-${breakpoint.width}x${breakpoint.height}.png`,
fullPage: false
});
console.log(`✓ Verified ${breakpoint.name} (${breakpoint.width}x${breakpoint.height})`);
}
});
test('UX enhancements load correctly', async ({ page }) => {
test.setTimeout(20000);
// Set mobile viewport
await page.setViewportSize({ width: 375, height: 667 });
// Login
await page.goto(`${STAGING_URL}/community-login`);
await page.fill('#user_login', 'test_trainer');
await page.fill('#user_pass', 'Test123!');
await page.click('#wp-submit');
await page.waitForLoadState('networkidle');
// Check that UX enhancement assets are loaded
const uxEnhancementsLoaded = await page.evaluate(() => {
// Check if HVACToast is available
const hasToast = typeof window.HVACToast !== 'undefined';
// Check if UX CSS is loaded by looking for specific classes
const uxStyles = Array.from(document.styleSheets).some(sheet => {
try {
return Array.from(sheet.cssRules).some(rule =>
rule.selectorText && rule.selectorText.includes('hvac-toast')
);
} catch (e) {
return false;
}
});
return {
hasToast,
uxStyles,
mobileNav: !!document.querySelector('.hvac-mobile-nav-container, .hvac-mobile-nav-toggle')
};
});
console.log('UX Enhancements status:', uxEnhancementsLoaded);
// At minimum, some UX elements should be present
expect(uxEnhancementsLoaded.hasToast || uxEnhancementsLoaded.uxStyles).toBe(true);
await page.screenshot({ path: `test-results/ux-enhancements-loaded.png` });
});
});