HEX
Server: LiteSpeed
System: Linux server315.web-hosting.com 4.18.0-553.54.1.lve.el8.x86_64 #1 SMP Wed Jun 4 13:01:13 UTC 2025 x86_64
User: globfdxw (6114)
PHP: 8.1.34
Disabled: NONE
Upload Files
File: /home/globfdxw/diasporameetsafrica.com/wp-content/plugins/extendify/playwright.config.ts
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
import { dirname, join, relative, resolve, sep } from 'node:path';
import { defineConfig, devices } from '@playwright/test';

const ROOT = resolve(__dirname);
const TEST_DIR = resolve(ROOT, 'tests/playwright');
const BASE_PORT = Number(process.env.BASE_PORT ?? 9400);
const WP_VERSION = process.env.WP_VERSION ?? 'latest';
const RUN_PROJECT = process.env.RUN_PROJECT;

const walkSpecs = (dir: string): string[] => {
	const out: string[] = [];
	for (const entry of readdirSync(dir)) {
		const full = join(dir, entry);
		const stat = statSync(full);
		if (stat.isDirectory()) {
			out.push(...walkSpecs(full));
			continue;
		}
		if (entry.endsWith('.spec.ts')) out.push(full);
	}
	return out;
};

const closestBlueprint = (specPath: string): string | null => {
	let dir = dirname(specPath);
	while (dir.startsWith(TEST_DIR) || dir === TEST_DIR) {
		const candidate = join(dir, 'blueprint.json');
		if (existsSync(candidate)) return candidate;
		if (dir === TEST_DIR) return null;
		dir = dirname(dir);
	}
	return null;
};

const projectName = (specPath: string): string =>
	relative(TEST_DIR, specPath)
		.replace(/\.spec\.ts$/, '')
		.split(sep)
		.join('/');

// First-line `// e2e:disabled` marker — see tests/playwright/scripts/discover-playwright-projects.mjs.
// RUN_PROJECT explicitly opting in to a disabled spec still wins (for local debug).
const isDisabled = (spec: string): boolean =>
	readFileSync(spec, 'utf8').split('\n', 1)[0].includes('e2e:disabled');

const specs = existsSync(TEST_DIR)
	? walkSpecs(TEST_DIR).filter(
			(s) => !isDisabled(s) || projectName(s) === RUN_PROJECT,
		)
	: [];

const blueprintPort = new Map<string, number>();
for (const spec of specs) {
	const blueprint = closestBlueprint(spec);
	if (!blueprint) continue;
	if (!blueprintPort.has(blueprint)) {
		blueprintPort.set(blueprint, BASE_PORT + blueprintPort.size);
	}
}

const projectBlueprint = new Map<string, string>();

const allProjects = specs
	.map((spec) => {
		const blueprint = closestBlueprint(spec);
		const port = blueprint ? blueprintPort.get(blueprint) : undefined;
		if (!port || !blueprint) return null;
		const name = projectName(spec);
		projectBlueprint.set(name, blueprint);
		return {
			name,
			testMatch: relative(ROOT, spec),
			use: {
				...devices['Desktop Chrome'],
				baseURL: `http://127.0.0.1:${port}`,
			},
		};
	})
	.filter((p): p is NonNullable<typeof p> => p !== null);

const projects = RUN_PROJECT
	? allProjects.filter((p) => p.name === RUN_PROJECT)
	: allProjects;

// Only spin up the webServer(s) the selected projects actually need. Spawning
// every blueprint's playground when only one project will run wastes boot time
// and burns ports.
const activeBlueprints = new Set(
	projects.map((p) => projectBlueprint.get(p.name)).filter(Boolean) as string[],
);
const webServers = [...blueprintPort.entries()]
	.filter(([blueprint]) => activeBlueprints.has(blueprint))
	.map(([blueprint, port]) => ({
		// PHP version is pinned per-blueprint via `preferredVersions.php` — the
		// CLI `--php` flag is silently ignored by wp-playground-cli. Pinned to
		// 8.3 to dodge a PHP 8.5 deprecation in vendor/react/promise that
		// breaks ?action=rest-nonce by printing inline when WP_DEBUG_DISPLAY is
		// on. Drop the pin once react/promise ships an 8.5-compatible release.
		command: `npx wp-playground-cli server --auto-mount --blueprint=${relative(ROOT, blueprint)} --wp=${WP_VERSION} --port=${port} --internal-cookie-store=true --login=false`,
		url: `http://127.0.0.1:${port}`,
		reuseExistingServer: !process.env.CI,
		timeout: 120_000,
		stdout: 'pipe' as const,
		stderr: 'pipe' as const,
	}));

// @wordpress/e2e-test-utils-playwright's RequestUtils HEADs process.env.WP_BASE_URL
// (default http://localhost:8889 — wp-env's default port) to find the REST root,
// regardless of each request context's configured baseURL. Pin it to the selected
// project's playground port so requestUtils.login() reaches the right server.
if (projects.length > 0 && !process.env.WP_BASE_URL) {
	const firstPort = new URL(projects[0].use.baseURL).port;
	process.env.WP_BASE_URL = `http://127.0.0.1:${firstPort}`;
}

export default defineConfig({
	testDir: TEST_DIR,
	globalSetup: './tests/playwright/global-setup.ts',
	forbidOnly: !!process.env.CI,
	retries: process.env.CI ? 1 : 0,
	workers: 1,
	// 30s default is too tight for this wp-playground suite on cold CI — the
	// reload-based save specs run ~25-30s even locally.
	timeout: 120_000,
	// Raise the per-assertion floor from 5s to the 15s specs already hand-patch.
	expect: { timeout: 15_000 },
	reporter: process.env.CI ? [['github'], ['html', { open: 'never' }]] : 'list',
	use: {
		trace: 'on-first-retry',
		video: 'retain-on-failure',
		screenshot: 'only-on-failure',
		testIdAttribute: 'data-test',
	},
	webServer: webServers.length > 0 ? webServers : undefined,
	projects,
});