Files
CompanySite/tests/static-assets.spec.ts
Clintchiz d402256547
Deploy to Production / Build & Verify (push) Failing after 5m56s
Ping Search Engines / Notify Search Engines (push) Successful in 2s
Deploy to Production / Pre-Deploy Tests (push) Has been skipped
Deploy to Production / Deploy to Railway (push) Has been skipped
Deploy to Production / Deploy to Render (push) Has been skipped
Deploy to Production / Deploy to VPS (PM2) (push) Has been skipped
Deploy to Production / Deploy to Fly.io (push) Has been skipped
Deploy to Production / Post-Deploy Verification (push) Has been skipped
Deploy to Production / Notify on Failure (push) Successful in 2s
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
E2E Test Suite / Smoke Tests (P0) (push) Failing after 11m26s
E2E Test Suite / Form Interaction Tests (push) Failing after 11m42s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 12m2s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 16m14s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 17m45s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 25m23s
E2E Test Suite / Security Header Tests (push) Failing after 7m55s
E2E Test Suite / Test Report Summary (push) Failing after 20s
E2E Test Suite / Mobile Device Tests (push) Failing after 2h49m9s
Uptime Monitor / Health & Response Time (push) Failing after 2s
Uptime Monitor / SSL Certificate (push) Successful in 2s
Uptime Monitor / Send Alerts (push) Failing after 3s
Uptime Monitor / Record Uptime Success (push) Has been skipped
First Init
2026-03-21 16:46:46 +05:30

263 lines
8.9 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('Static Assets and Links Verification', () => {
test.beforeEach(async ({ page }) => {
// Navigate to homepage before each test
await page.goto('/');
});
test('should load favicon correctly', async ({ page }) => {
const favicon = page.locator('link[rel="icon"]');
await expect(favicon).toHaveAttribute('href', '/favicon.svg');
// Verify favicon actually exists and loads
const response = await page.goto('/favicon.svg');
expect(response?.status()).toBe(200);
});
test('should reference correct domain in canonical URLs', async ({ page }) => {
const canonical = page.locator('link[rel="canonical"]');
const canonicalHref = await canonical.getAttribute('href');
// In production, should use workroot.in; in dev mode, may use localhost
if (canonicalHref?.includes('workroot')) {
expect(canonicalHref).toContain('workroot.in');
expect(canonicalHref).not.toContain('workroot.com');
}
// Should have a canonical URL
expect(canonicalHref).toBeTruthy();
});
test('should use correct domain in Open Graph tags', async ({ page }) => {
const ogUrl = page.locator('meta[property="og:url"]');
const ogUrlContent = await ogUrl.getAttribute('content');
// In production, should use workroot.in; never use workroot.com
if (ogUrlContent?.includes('workroot')) {
expect(ogUrlContent).toContain('workroot.in');
expect(ogUrlContent).not.toContain('workroot.com');
}
const ogImage = page.locator('meta[property="og:image"]');
const ogImageContent = await ogImage.getAttribute('content');
if (ogImageContent?.includes('workroot')) {
expect(ogImageContent).toContain('workroot.in');
expect(ogImageContent).not.toContain('workroot.com');
}
});
test('should have all internal navigation links working', async ({ page }) => {
// Check main navigation links
const navLinks = [
{ href: '/', text: 'Home' },
{ href: '/about', text: 'About' },
{ href: '/services', text: 'Services' },
{ href: '/portfolio', text: 'Portfolio' },
{ href: '/blog', text: 'Blog' },
{ href: '/contact', text: 'Contact' },
];
for (const link of navLinks) {
const element = page.locator(`a[href="${link.href}"]`).first();
await expect(element).toBeVisible();
}
});
test('should load external resources from whitelisted domains only', async ({ page }) => {
// Wait for page to fully load
await page.waitForLoadState('networkidle');
// Check CSP headers allow only whitelisted external domains
const response = await page.goto('/');
const cspHeader = response?.headers()['content-security-policy'];
expect(cspHeader).toBeDefined();
expect(cspHeader).toContain('https://fonts.googleapis.com');
expect(cspHeader).toContain('https://fonts.gstatic.com');
expect(cspHeader).toContain('https://images.unsplash.com');
});
test('should have working footer links', async ({ page }) => {
const footerLinks = [
'/privacy',
'/terms',
'/cookies',
];
for (const href of footerLinks) {
const link = page.locator(`a[href="${href}"]`).first();
await expect(link).toBeVisible();
}
});
test('should load blog images correctly', async ({ page }) => {
await page.goto('/blog');
// Check if blog post images load
const blogImages = page.locator('img[src*="/images/blog/"]');
const count = await blogImages.count();
if (count > 0) {
for (let i = 0; i < count; i++) {
const img = blogImages.nth(i);
await expect(img).toBeVisible();
}
}
});
test('should not have any broken internal links on homepage', async ({ page }) => {
const links = await page.locator('a[href^="/"]').all();
const brokenLinks: string[] = [];
const checkedLinks = new Set<string>();
// Known pages that are placeholders (not yet implemented)
const knownMissingPages = [
'/cookies',
'/services/web-development',
'/services/mobile-apps',
'/services/cloud-solutions',
'/services/it-consulting',
'/services/cybersecurity',
'/services/devops',
];
for (const link of links) {
const href = await link.getAttribute('href');
if (href && !href.includes('#') && !checkedLinks.has(href) && !knownMissingPages.includes(href)) {
checkedLinks.add(href);
const response = await page.goto(href);
const status = response?.status();
// 200 OK or 304 Not Modified are acceptable
if (status !== 200 && status !== 304) {
brokenLinks.push(`${href} (${status})`);
}
// Go back to homepage for next iteration
await page.goto('/');
}
}
// Log broken links for debugging
if (brokenLinks.length > 0) {
console.log('Unexpected broken links found:', brokenLinks);
}
expect(brokenLinks).toHaveLength(0);
});
test('should reference workroot.in in sitemap', async ({ page }) => {
const response = await page.goto('/sitemap.xml');
expect(response?.status()).toBe(200);
const content = await page.content();
expect(content).toContain('https://workroot.in');
expect(content).not.toContain('https://workroot.com');
});
test('should reference workroot.in in robots.txt', async ({ page }) => {
const response = await page.goto('/robots.txt');
expect(response?.status()).toBe(200);
const content = await page.content();
expect(content).toContain('workroot.in');
expect(content).not.toContain('workroot.com');
});
test('should have correct schema.org structured data', async ({ page }) => {
const jsonLdScripts = page.locator('script[type="application/ld+json"]');
const count = await jsonLdScripts.count();
expect(count).toBeGreaterThan(0);
for (let i = 0; i < count; i++) {
const scriptContent = await jsonLdScripts.nth(i).textContent();
if (scriptContent) {
const data = JSON.parse(scriptContent);
// Check for workroot.in references
const jsonString = JSON.stringify(data);
expect(jsonString).not.toContain('workroot.com');
// If it contains workroot domain, it should be workroot.in
if (jsonString.includes('workroot')) {
expect(jsonString).toContain('workroot.in');
}
}
}
});
test('should have API health endpoint working', async ({ page }) => {
const response = await page.goto('/api/health.json');
expect(response?.status()).toBe(200);
const data = await response?.json();
expect(data).toHaveProperty('status', 'ok');
});
test('should preconnect to external domains for performance', async ({ page }) => {
const preconnects = [
'https://fonts.googleapis.com',
'https://fonts.gstatic.com',
'https://images.unsplash.com',
];
for (const href of preconnects) {
const link = page.locator(`link[rel="preconnect"][href="${href}"], link[rel="dns-prefetch"][href="${href}"]`);
// Should have at least one preconnect or dns-prefetch link
await expect(link).toHaveCount(await link.count());
expect(await link.count()).toBeGreaterThanOrEqual(1);
}
});
test('should load apple-touch-icon correctly', async ({ page }) => {
const response = await page.goto('/apple-touch-icon.png');
expect(response?.status()).toBe(200);
});
test('should load og-image.jpg correctly', async ({ page }) => {
const response = await page.goto('/og-image.jpg');
expect(response?.status()).toBe(200);
});
test('should load logo.png correctly', async ({ page }) => {
const response = await page.goto('/logo.png');
expect(response?.status()).toBe(200);
});
test('should verify blog image assets exist on server', async ({ page }) => {
const blogImages = [
'/images/blog/ai-business.jpg',
'/images/blog/astro-intro.jpg',
'/images/blog/cloud-migration.jpg',
];
for (const imgPath of blogImages) {
const response = await page.goto(imgPath);
expect(response?.status(), `Blog image should load: ${imgPath}`).toBe(200);
}
});
test('should have correct domain in twitter:domain meta tag', async ({ page }) => {
const twitterDomain = page.locator('meta[name="twitter:domain"]');
const content = await twitterDomain.getAttribute('content');
expect(content).toBe('workroot.in');
});
test('should not have workroot.com referenced anywhere on homepage', async ({ page }) => {
const content = await page.content();
expect(content).not.toContain('workroot.com');
});
test('should have correct domain in all pages meta tags', async ({ page }) => {
const pagesToCheck = ['/', '/about', '/services', '/portfolio', '/blog', '/contact'];
for (const pagePath of pagesToCheck) {
await page.goto(pagePath);
const content = await page.content();
expect(content, `Page ${pagePath} should not reference workroot.com`).not.toContain('workroot.com');
}
});
});