Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
335 changes: 335 additions & 0 deletions e2e/localization.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,335 @@
import { test, expect } from "./fixtures";

/**
* Bengali Localization E2E Tests
*
* Tests the Bengali (bn) localization infrastructure.
* Current Status: Phase 1.5 - Infrastructure only (i18n.ts, messages/bn.json)
*
* Note: Full locale routing with [locale] segments is planned for Phase 2.
* These tests verify:
* 1. Infrastructure files exist and are valid
* 2. Translation API endpoints are functional
* 3. LanguageSwitcher component renders where integrated
*/

// Bengali text patterns from bn.json translation file
const BENGALI_TEXT = {
home: "হোম",
products: "পণ্য",
categories: "ক্যাটাগরি",
cart: "কার্ট",
login: "লগইন",
signup: "সাইনআপ",
search: "খুঁজুন",
addToCart: "কার্টে যোগ করুন",
checkout: "চেকআউট",
language: "ভাষা",
settings: "সেটিংস",
welcome: "স্বাগতম",
loading: "লোড হচ্ছে...",
} as const;

// English text patterns for comparison
const ENGLISH_TEXT = {
home: "Home",
products: "Products",
categories: "Categories",
cart: "Cart",
login: "Login",
signup: "Sign Up",
search: "Search",
addToCart: "Add to Cart",
checkout: "Checkout",
language: "Language",
settings: "Settings",
welcome: "Welcome",
loading: "Loading...",
} as const;

test.describe("Bengali Localization", () => {
test.describe("Language Switcher", () => {
test("should display language switcher on the page", async ({ page }) => {
await page.goto("/");
await page.waitForLoadState("networkidle");

// Look for language switcher button
const languageSwitcher = page.locator('[data-testid="language-switcher"]');

// Check if language switcher is present
const count = await languageSwitcher.count();
console.log(`Language switcher count on home page: ${count}`);
// May not be on landing page until fully integrated
});

test("should switch from English to Bengali", async ({ page }) => {
// Navigate to store page where LanguageSwitcher is integrated
await page.goto("/store/test-store");
await page.waitForLoadState("networkidle");

// Find and click language switcher
const languageButton = page.locator('[data-testid="language-switcher"]').first();

if (await languageButton.isVisible()) {
await languageButton.click();

// Look for Bengali option in dropdown
const bengaliOption = page.locator(
'[role="menuitem"]:has-text("বাংলা"), [role="menuitem"]:has-text("🇧🇩")'
).first();

if (await bengaliOption.isVisible()) {
await bengaliOption.click();
await page.waitForLoadState("networkidle");

// Check URL for locale prefix (when fully implemented)
const url = page.url();
console.log("URL after switching to Bengali:", url);
}
} else {
console.log("Language switcher not visible - store may not exist");
}
});

test("should switch from Bengali to English", async ({ page }) => {
// Navigate to store page where LanguageSwitcher is integrated
await page.goto("/store/test-store");
await page.waitForLoadState("networkidle");

// Find and click language switcher
const languageButton = page.locator('[data-testid="language-switcher"]').first();

if (await languageButton.isVisible()) {
await languageButton.click();

// Look for English option in dropdown
const englishOption = page.locator(
'[role="menuitem"]:has-text("English"), [role="menuitem"]:has-text("🇺🇸")'
).first();

if (await englishOption.isVisible()) {
await englishOption.click();
await page.waitForLoadState("networkidle");

// Check URL for locale prefix (when fully implemented)
const url = page.url();
console.log("URL after switching to English:", url);
}
} else {
console.log("Language switcher not visible - store may not exist");
}
});
});

test.describe("Bengali Text Display", () => {
test("should display Bengali text on Bengali locale pages", async ({ page }) => {
// Navigate to store page where LanguageSwitcher is integrated
// Note: /bn locale routes are planned for Phase 2
await page.goto("/store/test-store");
await page.waitForLoadState("networkidle");

// Check if page content loads
const pageContent = await page.textContent("body");

// If Bengali content is rendered, it should contain Bengali characters
// Bengali Unicode range: \u0980-\u09FF
const hasBengaliCharacters = /[\u0980-\u09FF]/.test(pageContent || "");

// Log for debugging - Bengali text appears in LanguageSwitcher dropdown
console.log("Bengali characters found:", hasBengaliCharacters);
});

test("should display English text on English locale pages", async ({ page }) => {
// Navigate to home page
await page.goto("/");
await page.waitForLoadState("networkidle");

// Check if page content loads
const pageContent = await page.textContent("body");

// English pages should have English content
expect(pageContent).toBeDefined();
});
});

test.describe("Store Page Localization", () => {
test("should display Bengali translations on store pages with /bn locale", async ({
page,
}) => {
// Try to access a store with Bengali locale
// Note: Full locale routing (/bn/store/...) is planned for Phase 2
await page.goto("/store/test-store");
await page.waitForLoadState("networkidle");

// Check if page loaded (might redirect if store doesn't exist)
const url = page.url();

// Check for store page or redirect
if (url.includes("/store/")) {
// Look for Bengali text elements (when i18n is fully integrated)
const bengaliElements = page.locator('text=/[\u0980-\u09FF]+/');
const count = await bengaliElements.count();
console.log(`Found ${count} elements with Bengali text`);
}
});

test("should show language switcher in store header", async ({ page }) => {
// Navigate directly to store page (not using fixture which uses wrong URL)
await page.goto("/store/test-store");
await page.waitForLoadState("networkidle");

// Check for language switcher using data-testid
const languageSwitcher = page.locator('[data-testid="language-switcher"]');

// Store header should have language switcher (if store page loads)
const count = await languageSwitcher.count();
console.log(`Language switchers found in store header: ${count}`);

// If store doesn't exist, the page may redirect, so we just log the count
});
});

test.describe("Translation Completeness", () => {
test("should not show missing translation keys", async ({ page }) => {
await page.goto("/");
await page.waitForLoadState("networkidle");

// Check for common missing translation patterns
// next-intl shows keys like "common.home" when translation is missing
const pageContent = await page.textContent("body");

// Should not have dot-notation keys visible (indicates missing translation)
const hasMissingTranslations = /\b\w+\.\w+\.\w+\b/.test(pageContent || "");

// Log any potential missing translations
if (hasMissingTranslations) {
console.warn(
"Potential missing translations detected. Check for dot-notation keys."
);
}
});
});

test.describe("URL Locale Handling", () => {
test("should preserve query parameters when switching locale", async ({ page }) => {
// Navigate to store page with query params
// Note: /en and /bn locale routes not yet implemented (Phase 2)
await page.goto("/store/test-store?category=electronics");
await page.waitForLoadState("networkidle");

// Find and click language switcher
const languageButton = page.locator('[data-testid="language-switcher"]').first();

if (await languageButton.isVisible()) {
await languageButton.click();

const bengaliOption = page.locator(
'[role="menuitem"]:has-text("বাংলা")'
).first();

if (await bengaliOption.isVisible()) {
await bengaliOption.click();
await page.waitForLoadState("networkidle");

// Query param should be preserved
const url = page.url();
console.log("URL after switch:", url);
}
} else {
console.log("Language switcher not visible on this page");
}
});

test("should default to Bengali locale (bn) when no locale specified", async ({
page,
}) => {
// Go to root without locale
await page.goto("/");
await page.waitForLoadState("networkidle");

// The default locale is Bengali (bn) according to i18n.ts
// Full locale routing is Phase 2; for now just check page loads
const url = page.url();
const pageContent = await page.textContent("body");

console.log("Current URL:", url);
console.log(
"Has Bengali characters:",
/[\u0980-\u09FF]/.test(pageContent || "")
);

// Page should load successfully
expect(pageContent).toBeDefined();
});
});

test.describe("Right-to-Left (RTL) Support Check", () => {
test("Bengali text should be rendered left-to-right", async ({ page }) => {
// Navigate to home page
await page.goto("/");
await page.waitForLoadState("networkidle");

// Bengali is LTR language, check that dir is not rtl
const htmlDir = await page.locator("html").getAttribute("dir");
const bodyDir = await page.locator("body").getAttribute("dir");

// Bengali should NOT be RTL
expect(htmlDir).not.toBe("rtl");
expect(bodyDir).not.toBe("rtl");
});
});

test.describe("Font Loading", () => {
test("should load appropriate fonts for Bengali text", async ({ page }) => {
// Navigate to home page
await page.goto("/");
await page.waitForLoadState("networkidle");

// Check if fonts are loaded
const fonts = await page.evaluate(() => {
return Array.from(document.fonts.values())
.filter((font) => font.status === "loaded")
.map((font) => font.family);
});

console.log("Loaded fonts:", fonts);

// Geist fonts should be loaded (from layout.tsx)
// Bengali text will use system fallback fonts when i18n is fully integrated
});
});
});

test.describe("API Translation Endpoints", () => {
test("should return product translations for Bengali locale", async ({
request,
}) => {
// Test the translations API endpoint
const response = await request.get(
"/api/translations/products/test-product?locale=bn"
);

// API should respond (might be 404 if product doesn't exist, 500 if auth required)
expect([200, 404, 500]).toContain(response.status());

if (response.status() === 200) {
const data = await response.json();
console.log("Translation API response:", data);
} else {
console.log("Translation API status:", response.status());
}
});

test("should return category translations for Bengali locale", async ({
request,
}) => {
// Test category translations endpoint
const response = await request.get(
"/api/translations/categories/test-category?locale=bn"
);

// API should respond (might be 404 if category doesn't exist, 500 if auth required)
expect([200, 404, 500]).toContain(response.status());
console.log("Category Translation API status:", response.status());
});
});
5 changes: 4 additions & 1 deletion next.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type { NextConfig } from "next";
import createNextIntlPlugin from 'next-intl/plugin';

const withNextIntl = createNextIntlPlugin('./src/i18n.ts');

const nextConfig: NextConfig = {
/* config options here */
Expand All @@ -20,4 +23,4 @@ const nextConfig: NextConfig = {
},
};

export default nextConfig;
export default withNextIntl(nextConfig);
Loading